领域驱动设计实践(一)(转)
分层构架
在分析领域驱动设计之前,我们需要先回顾以前的分层架构。“层”是一种体系结构模式,也是被广大软件从业人员用的最为广泛而且最为灵活的模式之一。其中最为大家所熟知的就是三层架构,那分层是什么?为什么要分层?传统的三层架构就是:表现层、业务逻辑层和数据访问层;其实所谓的分层要达到的目的就是,将具有不同的职责的组件分离开来,组成一套层内部高聚合,层于层之间低耦合的软件系统,这就是分层的目的;
在领域驱动设计的讨论同样也是建立在层模式的基础上的,但与传统的分层架构相比,它更注重领域架构和技术架构的分离。
传统的三层架构
我们所熟知的三层架构,自然就是有:表现层、业务逻辑层和数据访问层,我们用一个图来表示:
看图中的“基础构架层”,从实践的表现上来看,这部分内容可能就是一些帮助类,比如TextUtility之类。这些东西可以被其他各层所访问。而基于分层的概念,表现层只能跟业务逻辑层打交道,而业务逻辑层在数据持久化方面的操作,则依赖于数据访问层。表现层对数据访问层的内容一无所知。
从领域驱动的角度来看,这种分层的方式有一定的弊端。首先,为各个层面提供服务的“基础结构层”的职责比价紊乱,它可以是纯粹的技术框架,也可以包含或处理一定的业务逻辑,这样一来,业务逻辑于“基础结构层”之间就会存在依赖关系;其次这种结构过分突出了“数据访问”的地位,把“数据访问”与“业务逻辑”放在了同等的位置,这就形成了现在我们的”数据驱动“的开发方式,对于软件我们的第一直觉就是:”这个数据表该如何设计!“
在微软.net3.0开始,引进了EntityObject的概念,在习惯了DataTable操作的时代,EntityObject所带来的灵活性是无法相比的,但这暗示了一场软件设计的思想革命,即使是微软也要按照这种思想前行,这就是需要摆脱原来的”数据驱动“走向”领域驱动“开发的道路,在长久的数据驱动的操控下,仍然有大部分从业人员成天抱着数据库不放,应对软件需求时,”我要实现某个功能,我的数据库该如何设计呢?“。其实是我们把软的目的搞错了,软件研究的是如何使用计算机来解决实际(领域)问题,而不是去研究数据应该如何保存更合理,所以软件设计应该是”数据驱动“走向”领域驱动“,而领域驱动设计的实践经验正是为了设计和开发大型复杂的软件系统提供了实践指导。
微软在领域驱动上的进步,从DataTable这一纯粹的数据组织形式,到EntityObject这一实体对象,微软带给我们的不仅仅是技术框架,更是一套面向领域的解决方案。
.NET 4.0来了,随之而来的是实体框架(EntityFramework,简称“EF”),在本系列文章中,我将结合领域驱动设计的实践知识,来剖析EF的具体应用过程,当然,现在的EF还并不是那么完善,我也非常期待能够看到,今后微软能够继续发展和完善EF,使其成为微软领域驱动工具箱中的重要角色。
领域驱动设计的分层
领域驱动设计将软件系统分为四层:基础构架层、领域层、应用层和表现层。与上述三层相比,数据访问层已经不在了,它被移动到了基础构架层。
基础结构图:该层专为其它各层提供技术框架支持。注意,这部分内容不会涉及任何业务知识。众所周知的数据访问的内容,也被放在了该层当中,应为数据的读写是业务无关的
领域层:包含了业务所涉及的领域对象(实体、值对象)、领域服务以及他们之间的关系。这部分内容的具体表现形式就是领域模型(Domain Model)。领域驱动设计提倡富领域模型、即尽量将业务逻辑归属到领域对象上,实在无法归属的部分则一领域服务的形式进行定义。
应用层:该层不包含任何领域逻辑,但它会对任务进行协调,并可以维护应用程序的状态,因此,它更注重流程性的东西。在某些领域驱动的实践中,也会将其称为”工作流层“。应用层是领域驱动中最争议的一个层次,也会很多对其职责感模糊不清。
表现层:这个好理解,跟三层里的表现层意思差不多,但请注意,”web服务“虽然是服务,但它是表现层的东西
从上图中可以看到,表现层于应用层之间是通过数据传输对象(DTO)进行交互的,数据传输对象是没有行为的POCO对象,他的目的只是为了对领域对象进行数据封装,实现层与层之间的数据传递。为何不能直接将领域对象用于数据传递?因为领域对象更注重领域对象,而DTO更注重数据,不仅如此,由于”富领域模型“的特点,这样做会直接将领域对象的行为暴露给表现层。