代码改变世界

最近架构随想

2014-07-28 08:19 by 圣殿骑士, 6108 阅读, 62 评论, 收藏, 编辑

今天新加坡放假,闲来无事就发一篇博客:一则总结归纳项目构架经验,审视并逐步提高自己;再者分享最近学习所得,希望各位能讨论并给些建议。六月三十日从原来公司离职,七月一日入职新公司,不知不觉已经快一个月了。最近忙于学习新的行业知识以及项目的重构设计,没有时间发博客,也没有时间回复邮件及博文评论,忘各位见谅!

今天发几张项目重构设计草图,如果大家对项目分层与文件夹结构比较感兴趣,可以参考几年前弦哥.Net项目分层与文件夹结构大全(最佳架子奖,吐槽奖,阴沟翻船奖揭晓),这次的架构方案基本是之前架构经验第一次在保险行业的使用,希望各位能积极探讨并给些意见!

整体方案:

根据个人经验,架构决定项目的成败以及高度,所以在编码之前一定要设计好项目的整体规划和架构。好的架构或者考虑比较全面到位的架构会极大的帮助团队,对项目起到灵魂的作用;糟糕的设计往往会把整个项目组带入泥潭或者恶性循环,对项目直接致命打击!

回归正题:

  • 整个架构分为Online(Web Application)和Offline(WPF Application)两部分。
  • Online(Web Application)需要支持不同的设备及浏览器,所以采用Bootstrap和ASP.NET MVC with Razor作为View,KnockoutJs作为MVVM框架。UI Designer设计好UI,然后由前端工程师绑定相应的UI Model到UI,后端工程师则负责相应的OOAD以及业务处理。
  • Offline(WPF  Application)需要在没有网络的情况下能正常工作,所以采用WPF  XALM作为View,MVVM Light作为MVVM框架。UI和后端的处理以及任务分配和Online(Web Application)基本一致。
  • Services :设置了Switch功能,可以配置是否使用WCF或者Web API或者直接调用Dll。
  • Domain Model:始终是应用程序的核心,必须投入大量精力,按照面向对象的分析和设计 (OOAD) 进行设计同时按照OOP进行开发。
  • Infrastructure:主要包括数据访问组件、通用权限框架、异常和日志处理组件、IOC/AOP功能、缓存机制,邮件,配置等基础或常用功能。
  • 行业知识:由于项目牵涉到具体的行业(保险业),所以在业务流程中创建了Insurance Engine,专门处理保险相关的基础功能。
  • 权限系统:由于整个项目比较庞大,再加上其他系统也需要用到同样的权限判断,所以创建了一个新的权限数据库,用来存储及处理权限相关的所有数据及规则,所有用户则来源于三个数据源(SQL Server, DB2和Active Directory)。
  • Unit Test:每一层都有单独的单元测试,方便项目功能自测,维护,重构,升级以及管理。28-7-2014 12-31-12 AM

组件之间的详细关系如下:

28-7-2014 12-27-11 AM

各层之间的执行顺序如下:

28-7-2014 12-34-29 AM

权限系统:

  • 用户来源于三个数据源(SQL Server, DB2和Active Directory)。
  • 现实世界和系统通过角色进行关联,现实世界的用户及组的变化尽量不要影响到系统。
  • 一个用户可以有多个角色,一个角色也分配给多个用户。
  • 权限分为功能权限和数据权限。
  • 权限系统要提供给几套系统使用,全部的接口通过Service的形式提供出来。

security

由于时间有限,设计可能存在诸多不足之处,如果大家有不同的意见或者建议,不妨在评论中指出,以便互相学习且共同提高!


作者:圣殿骑士
出处:http://www.cnblogs.com/KnightsWarrior/
关于作者:专注于微软平台项目架构、管理和企业解决方案。自认在面向对象及面向服务领域有一定的造诣,熟悉设计模式、TDD、极限编程、领域驱动、架构设计、敏捷开发和项目管理。现主要从事WinForm、ASP.NET、WPF、WCF、WF、Silverlight 、Biztalk、Windows Azure等云计算方面的项目开发、架构、管理和企业培训工作。如有问题或建议,请多多赐教!
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。如有问题,可以邮件:KnightsWarrior(at)msn(dot)com  微博:圣殿骑士微博  联系我,非常感谢。

40
0
(请您对文章做出评价)
? 上一篇:关于新加坡IT薪酬
Add your comment

  1. #51楼[楼主] 圣殿骑士   2014-07-28 21:36
    @dotnet技术网
    引用我也有类似的想法,但真正开发起来,就非常麻烦,梦想很美好,现实很骨干。

    是的,很多时候实施起来比架构设计还难,不过类似项目经历多了就更容易一些了!
  2. #52楼[楼主] 圣殿骑士   2014-07-28 21:38
    @Da ge
    引用必须推荐,最好能有个demo让小伙伴们学习下

    DEMO还处在实施阶段!
  3. #53楼[楼主] 圣殿骑士   2014-07-28 21:40
    @春色园
    引用架构应该适应业务!!

    是的,这个架构就是适应业务和需求而画的,具体模块之间的划分还有几个图——用例图,类图,部署图等,由于与项目有关,没有公布出来。
  4. #54楼 jlzhou   2014-07-29 07:21
    期待代码示例 感谢
  5. #55楼 stoneniqiu   2014-07-29 08:14
    这样的项目 好想加入~~
  6. #56楼   2014-07-29 13:43
    请问一下你们单元测试用的什么框架
  7. #57楼 owlbcc   2014-07-29 14:32
    wpf的和mvc的两个viewmodel能不能合到一起?两个系统之间是不是差异还挺大的?
  8. #58楼 muki   2014-07-29 17:08
    架构太过于复杂了.
  9. #59楼 flyfish1986   2014-07-30 13:34
    来了!
  10. #60楼 HelloNet   2014-08-04 13:52
    看上去很牛逼的样子
  11. #61楼 Pansen   2014-08-05 08:58
    mark
  12. #62楼 高僧   2014-08-11 15:01
    楼主,上面这几图是用什么工具画的?

页面生命周期与加载顺序

页面加载顺序

page-> child master->parent master->child control-> parent control

PreInit事件

它是页面生命周期的入口点。该事件被引发时,页面尚未与母版页和主题相关联。但页面滚动条位置已被恢复,被投递的数据变为可用,且所有的页面控件已被实例化,其属性也已基于在ASPX源中的默认值进行了设置(注意,如果没有在.aspx源中显式指定,这时的控件是没有ID的)。在这个阶段中,可以对母版页进行调换,或对主题进行编程。该事件仅对页面有效。IsCallback、IsCrossPagePostback和IsPostBack会在这时被设置。 【132】

Init事件

1在这个阶段,母版页和主题(如果分别存在)会被设定,不能再被更改。页面处理程序(即Page类的ProcessRequest方法)开始执行,对所有子控件进行迭代,使其有机会在上下文环境下初始化它们的状态。所有子控件都有自己的OnInit方法,后者以递归方式被调用。对于控件集合中的每个控件,都设置有命名容器和特定ID(如果没有在源中分配)。 Init事件首先会处理子控件,然后是页面。在这个阶段,页面和控件通常开始加载其部分状态。

2此时,视图状态尚未被恢复。

InitComplete事件

该事件是ASP.NET 2.0引入的,页面专有,用于指示初始化子阶段的结束。对于页面来说,在Init和InitComplete事件之间只有一个操作会执行——

1启用视图状态的变更跟踪功能。视图状态的跟踪是这样的一种操作,它最终使控件能够真正地将所有以编程方式添加到ViewSatae集合中的值,存储在持久性介质中。简而言之,对于没有实施视图跟踪的控件,添加到其ViewState中的值将在回发间丢失。
在控件引发各自的Init事件后,视图状态跟踪会立即启动,页面也不例外(归根结底,页面也是一种控件)。 要点:对于上述说明,有一点需要注意:在InitComplete前,任何写入ViewState集合的 值,在下一次回发时都不再可用。(在刷新页面后,在这个事件前,你取不到viewstate里面的值)

对于ASP.NET 1.x,必须等待Load事件被引发,才能安全地更改页面和控件的视图状态。 视图状态的恢复 如果页面因回发而被处理(即,IsPostBack属性为true),隐含字段__VIEWSTATE的值会被恢复。隐含字段__VIEWSTATE用于在请求结束时,保存所有控件的视图状态。页面的整体视图状态是一种调用上下文,包含页面每个组成控件上一次发往浏览器的状态信息。 在这个阶段,每个控件会获得更新其当前状态的机会,恢复其上一次请求时的状态。视图状态的恢复过程不会引发任何事件。如果需要对此进行定制,则必须借助于LoadViewState方法的重写(该方法在Control类中为受保护的虚拟成员)。 【133】 处理被投递的数据 HTTP请求中打包的所有客户端数据(即所有定义在<form>标签中输入字段的内容),会在这时被处理。被投递的数据通常采用下面这种形式: TextBox1=text&DropDownList1=selectedItem&Button1=Submit 该字符串用的键/值(name/value)对被“&”分隔。这些值会被加载到一个内部使用的集合当中。页面处理程序会试图寻找被投递集合中的名称与页面中控件ID的匹配项。如果找到匹配项,处理程序会检查该服务器控件是否已实现IPostBackDataHandler接口。如果已实现,该接口的方法会被调用,为使用被投递数据更新该控件状态提供机会。具体来讲,页面处理程序会调用该接口的LoadPostData方法。如果它返回true(即,状态已被更新),该控件将被添加到一个独立的集合中,等待进一步指示。 如果没有找到与被投递的名称对应的服务器控件,它将被搁置于一临时的独立集合中,稍后再试。

PreLoad事件

PreLoad事件是ASP.NET引入的,仅用于指示页面已完成系统级的初始化,即将进入另一个阶段。接下来的阶段会为页面中用户代码的执行提供机会,为执行和呈现对该页面做进一步配置。只有页面会引发该事件。

Load事件
Load事件首先由页面引发,之后以递归方式分别由所有的子控件引发。这时,页面中的控件树会被创建,各控件的状态完全反映之前的状态,并获得了从客户端投递过来的所有数据。对于执行处理逻辑和页面行为的初始化代码,页面已做好准备。这时访问控件属性和视图状态是绝对安全的。

posted @ 2012-10-03 11:59  hudasm  阅读(522)  评论(0编辑  收藏  举报