前面介绍了应用程序框架的一个重要组成部分——公共操做类,并提供了一个数据类型转换公共操做类做为示例进行演示。下面准备介绍应用程序框架的另外一个重要组成部分,即体系架构支持。你不必定要使用DDD这样的架构,使用单层架构和普通三层架构同样能够,不过你若是但愿得到更进一步的复用性和封装度,使用更加面向对象的技术是必经之程。程序员
我在2010年之前还在使用古老的ASP.NET WebForm和原始的Ado.Net。以前我有个观念:.NET技术发展太快,跟着微软屁股后面跑太累,因此只使用它一些原始的东西,本身封装一下也能知足工做上的需求。对于像Linq这样的技术只是随便看了下,特别是当时不少人告诉我Linq已死,千万别学,我当时很喜欢这样的言论,由于不学习新知识就有了充分的理由。编程
到了2010年,我有一次上博客园,浏览了一些文章,发现充满各类缩写和名词,什么Dto、工做单元一类,我才知道新一代的.Net技术已经开始普及,我已经Out了。以后我开始学习EF和MVC,在刚开始接触EF的时候,我从一些博客了解到,为了发挥EF的威力,必须使用DDD进行设计。为了扫清拦路虎,我购买了几本DDD的书来学习,学习过程当中才发现面向对象和敏捷开发才是关键,因而开始大量购书,一发不可收拾,四年时间买了接近两百本后,终于把基础补起来一点。设计模式
DDD的核心思想是描述如何使用面向对象的方法对业务领域建模,怎样得到更好的领域模型。虽然看了很多DDD的资料,但仍是感受它异常抽象,另外面向对象的思想也很难进步,可能和前些年的编程习惯有关,已经习惯于从数据的角度考虑问题,造成了思惟定势。架构
DDD虽然抽象,但它仍是提供了一些技术上的支持。大部分人都是从DDD分层架构入手来进行学习和实践,固然,DDD并非分层架构,分层架构只是DDD的一个技术构造。下面简单介绍一下我对DDD分层架构的理解,因为我使用DDD的时间不长,我所描述的观点都是我本身的一些开发经验,不必定正确,欢迎各位高手批评指正,共同进步。框架
DDD分层架构整体上和三层架构类似,不过对各层提出了更具体的职责和构造块。我也常常与一些在使用DDD分层架构的朋友交流,我问他们DDD分层架构与普通三层架构有何区别,大部分人都感受差很少,除了一些名词术语有所变化。若是你也是这个感受,那么可能本文对你是有帮助的,由于我明显感受出它们之间有所不一样。分布式
DDD分层架构与传统三层架构示意图以下。单元测试
(领域驱动设计分层架构示意图)学习
(传统三层架构示意图)测试
DDD分层架构与传统三层架构最重要的区别多是重心不一样,即传统三层架构的重心在业务逻辑层,而DDD分层架构的重心在领域层。spa
面向对象设计的核心是基于业务概念建模,并映射到代码中,这样的好处是减轻程序员将业务概念转换到技术的负担,由于更容易理解。传统三层架构虽然也把业务概念转换到实体层的Model对象,但实体层只是一个辅助设施,这些Model只是用来装数据的容器,做用并不显著。DDD分层架构把领域层提到核心地位,这些Model成为业务逻辑的一个主要放置场所。
使用DDD分层架构的第一个好处就是业务逻辑高度内聚到领域层,换句话说,若是有逻辑问题,找领域层就对了。对于这一点,有些人认为传统三层架构也能够,找业务逻辑层不是同样吗?这多是大多数对领域驱动设计分层架构认识没法突破的关键。
虽然你能够按照分层架构的要求,把所有业务逻辑都写到BLL层,但你没法精肯定位你须要的业务逻辑究竟处于什么位置,换句话说,你须要业务逻辑的一个惟一访问点。因为你没法轻易找到业务逻辑的访问点,因此产生冗余代码就再所不免,一段相同或类似的冗余代码会在多个地方产生,从而致使可维护性的下降。经过强制约束代码和目录规范以及提取公共方法能够缓解部分问题,但要从根本上解决,你还得向面向对象求救。
那么,哪里是业务逻辑最好的落脚点,最直观,最容易被你们想到的惟一访问点在哪呢?好比你要处理一个订单,让你到其它地方去找处理订单的代码,你天然找起来困难。那么若是这段代码处于订单实体的内部,状况就大不相同了,你能够在最短的时间内找到它。在领域实体中内聚业务逻辑,能够为你建立一个业务逻辑的惟一访问点。你们之后须要某个逻辑的时候,先看看实体中有没有本身须要的,这样就能显著下降代码冗余,从而更好维护。
因此,个人第一条DDD使用经验就是,使用充血模型,将业务逻辑尽可能放到领域实体中。充血模型有不少争论,不过你大可没必要理会别人的说法,本身实践才能出真知。用得不爽,你后面不用就是了,对你基本没啥影响。目前我使用充血模型,感受它主要的问题是,若是采用分布式架构,好比中间采用WCF远程调用,须要经过一层专门的DTO来进行传输,并且须要增长一个远程外观的服务,会致使工做量上升。
当把充血模型用起来之后,下一步是要把聚合用起来。聚合这个概念很好理解,就是包含关系。在UML中有两种包含关系,第一种叫聚合,表示比较弱的包含关系,聚合内部的东西在外面能够直接访问。第二种叫组合,即组成聚合,是很强的包含关系,表示外部的对象由内部的多个子对象组成,内部的子对象在外面不能直接访问,必须经过外部的对象间接引用。DDD虽然用了聚合这个词,但它表示UML中的组成聚合,因此它把外部的对象称为根,即聚合根,要访问内部对象,必须先访问聚合根。
概念上的理解,除了能吹吹牛之外,没多大帮助。我在刚接触DDD的时候,也能理解聚合的概念,提及来同样口沫横飞,但真正用起来过了差很少一年。除了我反应比较迟钝之外,还有一个缘由是被以前以数据为中心的思惟定势所束缚。
我也常常下载一些DDD的Demo来学习,可是这些例子大多都很是简单,因此我主要仍是依靠看书和本身摸索。我刚开始的用法是一个表对应一个领域实体,每一个领域实体对应一个仓储。我在使用的过程当中,隐隐发现哪里不对,可是没法找出具体的缘由。通过大半年,我也使用DDD开发了几个简单的项目,逐步积累了一些经验,在一次看书的时候,我忽然领悟到个人DDD用法主要毛病是依赖关系混乱,而解决这些依赖关系的手段就是聚合。
聚合的主要影响是显著减小仓储数量,以及集中管理高度依赖的相关实体。把高度相关的实体内聚到一个聚合中,能够把这些依赖关系封装到一个更小的空间,外部只与聚合根打交道,与聚合内部子对象的依赖关系就会明显下降。一个聚合对应一个仓储,而不是一个实体对象一个仓储,能够减小仓储数量,从而进一步下降依赖关系。
后面我从新阅读了一些博客和书籍,发现别人其实都说清楚了,只是本身当时看过去没有理解而已,这真是纸上得来终觉浅 绝知此事要躬行。
个人第二条DDD使用经验是,把高度相关的实体封装到聚合中,为每一个聚合根建立一个仓储。
观察上面的DDD分层架构示意图,会发现领域层只依赖于应用程序框架服务,仓储采用了接口分离模式将实现和接口分离到不一样的程序集,领域层中只包含仓储的接口,这个设计让领域层很是纯净,和外部的依赖关系降到最低。这对咱们意味着什么?更低的依赖让咱们能够方便的对业务逻辑进行单元测试,特别是采用了TDD方式的话,这一点将显得尤为重要。咱们能够在单元测试中使用模拟框架对仓储以及外部依赖进行模拟测试,从而大幅度提高业务逻辑的稳定性和健壮性。
另外,观察传统三层架构,业务逻辑层通常直接依赖数据访问层,让单元测试变得困难,从而转向更粗粒度的集成测试。
经过上面的分析,能够看到采用DDD分层架构能够得到比传统三层架构更好的可复用性、可维护性、可测试性等。
固然不可能把全部业务逻辑所有放入领域实体中,有些功能须要操做多个实体,或者须要使用某些设计模式,这时候须要使用领域服务。这里的要点是尽可能把领域服务的操做委托给领域实体,由于这样业务逻辑能够更加集中。
DDD分层架构还有一些构造块,我会在后面的文章详细介绍。若是没有介绍到的,说明我还处于学习和摸索阶段,尚未多少心得,等我有些经验之后再告诉你们。
如今来总结一下。
使用DDD分层架构有哪些好处
个人DDD分层架构使用经验
最后,提醒一下,咱们使用一些DDD分层架构构造块,可能并不算真正用上了DDD。可是,咱们的目标是使用DDD吗?不是,咱们的目标是把业务逻辑作得更稳定,更好维护。因此不用在乎本身使用的技术正不正宗,标不标准,只要比之前更好,就应该坚持下去。
.Net应用程序框架交流QQ群: 386092459,欢迎有兴趣的朋友加入讨论。
谢谢你们的持续关注,个人博客地址:http://www.cnblogs.com/xiadao521/