本最小架构在1.0版本的基础上进行了进一步改进,适用于B/S结构的企业级系统应用,本系统依然站在巨人的肩膀上(马丁福勒),是在.NET领域中的实现模式的一种探索,供大家研究学习并应用于实际项目中。架构整体风格为三层架构,做到了松散耦合、可扩展性、易维护性等诸多有点。其较之前一个版本1.0而言已有较大改观和进步,主要体现在以下几点:
1、Spring深度整合MVC和Hibernate,MVC当“导演”,Spring当“管家”,Hibernate当“采购总监”,(*^__^*)
2、Spring升级到1.3.2,Hibernate升级到3.2,MVC依然为3.0
3、架构模块职责进一步划清,进一步提高了松耦合。
4、引入SpringAOP编程,解决DAO异常日志记录。
5、重新改善了Log4net组件的编程模式。
6、将对象依赖配置文件集中管理,一改过去分散管理的状态。
7、完善了Spring事物配置的通用性。
8、绝大部分对象之间依赖都使用Spring“依赖注入”,提高系统松耦合性,以及便利的实现了功能类的“单例性。
9、改Facade层为Segregate层。Facade层为远程调用,而使用Segregate(隔离)层在这里更加适用,并增加接口。
10、丰富样例,添加了编程规范注释。并且可以使用Ctrl+F5运行出样例。
代码:
EnterpriseArchitecture-2.0.part1.rar
EnterpriseArchitecture-2.0.part2.rar
运行环境:
VS2010、MVC3、.NetFramework4.0、Window XP以上、SQLServer NorthWind数据库
架构图:
其余设计和1.0版本类似,请参考1.0版本资料
企业级分层架构视图
一、三层架构
在福勒阐述的企业级应用常见的基于三层的架构模式中(Transaction Script、DomainModel、Table Module以及Active Record),建议我们无论项目大小统一采用DomainModel模式。这样有很多好处,统一架构风格,统一了思想和编程模式,为应用升级带来了极大的可扩展、易维护的空间,研究表明在使用“领域模型”模式的系统中对于大规模业务逻辑的系统具有极强的适应能力。
二、项目开发架构
如下图所示,在.net环境中我们实现三层架构的类库结构分为如下几个模块类库。各个模块的功能职责定义如下:
1.Web:这里是MVC应用,表示模块和具体的应用相关连,可以是ASP.NET、WCF或Console等应用,
她应 该只关注于对客户的表示,不关心业务。MVC应用中Control职责就应该如此。
2.Model:这个模块即为DTO(数据传输对象),它的作用主要是为表示层的视图提供数据封装。MVC应用
中这里就充当了Model模块的分离。
3.Segregate:即为隔离层,隔离层的作用将是将表示层和业务层彻底分离,实现两个层可移植性,互不
依赖。所以她在这里的基本职责是为两个层的数据做类型转化以及验证表示层数据有效性。
很多人认为 因为MVC框架提供强大的验证数据有效性,所以数据验证应该在MVC的Model中验证,其实不然,因为既然是想做出高度可移植性的系统,必然系统的表示层将来可能会换成别的应用,一旦表示层换了,那么自然MVC的数据验证就不存在了,这个时候你就不得不在新的表示层项目中重写数据有效性验证了,悲剧!
当然,如果你的应用永远不会改成别的表示层,那么使用MVC的Model验证方式确实能够减轻不少编程压力,而且代码简洁,并提供客户端和服务端一致的验证技术。
4.Service:即为应用逻辑层,它是一个粗粒度的逻辑封装,几乎相当于系统的某个用例(用户的触发事件),相当于一个操作脚本。几乎可以写成一种公式:业务=应用逻辑+领域逻辑+数据逻辑。这个公式强调了这三大逻辑的分离理论,提高系统可移植性、松散耦合性。领域逻辑分离为Domain库,而数据逻辑分离为DAO库。同时这里也是事务运行区。
5.Domain:即为领域模型,虽然大家很少会去建立领域模型,但我们的数据库中的实体实际上就是领域模型的一部分,而且十分相似,领域模型的对象拥有属性和方法。其方法就是我们指的“领域逻辑”。
6.DAO:即为数据访问层,很多人理解为就是访问数据库的,其实它的职责还包括一切持久化数据的访问(文件、视频、图片等)。
一个关于DAO的争论是,他应该是什么样的,有人趋向于“通用查找”,而有人倾向于具体“数据逻辑”方法,这样的结果是前者的Dao中代码是固定的几个匹配方法,而后者Dao就成了一个Repository(资源库),其中包含了大量的各种数据查找逻辑,因为它完全把操作数据的逻辑从应用逻辑中分离出来了,这两种应用模式都有人使用。
但我更倾向于后者,因为这样也有许多好处,其一,就是它将数据逻辑分离出来,这样以后系统更换了数据库或数据访问组件,我们只需要更改一下Dao方法中的实现即可,而无需改动系统其它部分,提高了系统可移植性和松散耦合性,Very Good!其次,就是减轻了Service的负担,在一个简单的增删改查系统中“数据逻辑”耦合在“应用逻辑”中还好,不会使代码过长,但在长流程的业务系统中,分离出“数据逻辑”无疑是明智之举。
再来说说前者的情况,前者就是想把“数据逻辑”和“应用逻辑”一起放到Service中,这样在他们看来的好处是,所有的Dao方法是固定的,构造取数据的逻辑由Service完成,Service只传递一个查询条件给Dao即可。但这也会有一些不足,其一,就是在长流程的业务系统中Service忙着实现流程操作,而此时再给她增加构造数据查询条件的代码,这样会使得其代码变得冗长,也不容易阅读。其次,为了实现业务层和数据层分离,我们是不会在Service中写耦合第三方数据访问组件的API的(如:Hibernate),这样就会促使你不得不自己实现一套数据查询条件构造类,而如HQL语句却不能使用。
基于“分离关注点”的原则和这样那样的理由,我觉得使用“数据逻辑”分离的模式比较理想。