对三层架构到领域驱动架构进化过程的理解

      领域驱动架构由微软西班牙团队推出以来,已经在很多项目中得到了应用,但是你也会发现目前还有很多项目或早期项目仍然在使用三层架构。在项目中这两种架构模式都有使用到,这里总结下我自己的体会。

      一、首先看看,经典的三层架构:

 

   通过架构图可以直观的知道三层架构的目标是:降低各层之间的耦合度、通过接口依赖让各层有更好的扩展性。通常三层架构是从上到下的引用方式,不存在各层间的跨越。三层的划分跟业务基本是无关的,通常在项目中使用三层架构我们会基于每个模块创建三层代码。

二、  再看看领域驱动的架构:

 这里讲讲各层的含义和内容(网上都能找到):

基础结构层:这个层其实是跨越所有层的,包含了系统使用到的所有基础设施,一般会细分为两个小类,用于数据持久化的内容会单独列分出来。而其它部分如:访问的通用技术框架,比如异常捕获与处理、日志、认证、授权、验证、跟踪、监视、缓存等则会归类到另一类型中。

领域模型层:展现业务/领域逻辑、业务处理状态,以及实现业务规则,它同时领域模型层也包含了领域对象的状态信息。这一层是整个应用程序的核心部分,它可以包含下面这些概念和内容:
实体(Entities)
值对象(Value Objects)
领域服务(Domain Services)
仓储契约/接口(Repository Contracts/Interfaces)
聚合及其工厂(Aggregates and Factories)
聚合根(Aggregate Roots)
规约对象(Specifications)
这一层通常定义内容是领域对象和业务接口(core层)。

应用层:应用层用于协调领域模型与其它应用组件的工作,以完成一个特定的、明确的系统任务。这种协调可以包括:事务调度、UoW(Unit Of Work,PoEAA)的执行,以及调用一些系统必须的处理任务等。应用层同时还可以包括应用程序的优化、数据的转发和格式转换等工作,当然,我们将这些工作统称为“任务调度”,至于每个任务的核心部分,应用层都会将其转发到下层去处理。应用层通常会被看做是一种“业务层外观(Business Facade)”,但它却不仅仅是转发领域模型层的处理请求/反馈那么简单。它通常可以包含下面这些内容:

  • 通过仓储契约(Repository Contract)来访问持久层机制,以读取或保存领域对象。注意这里访问的是仓储契约,而并非仓储的具体实现。仓储的具体实现是基础结构层的内容
  • 对来自于不同领域对象的数据进行组织和整理,以便能够让分布式服务层更有效地传递这些数据。通常,我们会将数据整理在数据传输对象(Data Transfer Object,PoEAA)中,例如WCF的Data Contracts
  • 管理和维护应用程序的状态(而不是领域模型中领域对象的状态)
  • 协调领域对象之间、领域模型与基础结构层组件之间的协作关系。比如在银行转账系统中,资金从一个账户转移到另一个账户,首先需要通过仓储读取“账户”领域对象,然后在领域对象上进行转账操作(可以是“账户”本身的行为,也可以是,按Evans的举例,使用领域服务(Domain Service))。或许在完成转账后,无论成功与否,都需要向外发送电子邮件,这就需要基础结构层的电子邮件组件协作完成
  • 应用服务(Application Services):首先需要注意,DDD中提到的服务与平时所说的Web Service等并不是一个概念,它可以存在于应用层、领域模型层甚至基础结构层。DDD中Service所表述的概念,其实是“无法归结到任何一个对象”的一系列操作的集合,因此,Service通常是在协调不同对象之间的工作。应用服务也是如此,它会对其它下层组件(比如领域模型层与基础结构层)进行协调
  • 业务工作流(Business Workflow):业务工作流并非必须的,对于某些由特定步骤组成的业务过程,引入业务工作流会使问题变得简单

表现层(Presentation):该层的主要职责是通过用户界面向用户展示必要的数据信息,同时接收用户的反馈。该层中的组件主要实现了与图形界面、用户操作捕获、数据转发等用户界面功能。建议根据项目的实际情况,选用相关的模式(比如MVC、MVP或者MVVM等)将这些组件细分到更小的层中。

三、领域驱动的特点
和三层架构不同领域驱动并非从上至下的依赖关系,而是跨越式的,从这个图更能直观体会:

  1. 领域驱动的基础设施是跨越所有层的
  2. 应用层可以同时访问领域层和基础设施中的持久化层
  3. 当然领域层可以依赖持久化层是比较常规的

   为什么会这样呢,随着Ioc、orm技术成熟,领域驱动引入了这些概念,三层架构的可扩展性直接通过各种IOC框架就解决了,不需要再强调三层隔离。这让领域驱动架构分层更多的去关注业务也就是领域。

从业务角度讲领域层是核心,他定义了领域对象和核心的接口,具体实现通过Ioc注入持久层的处理即可。这一层引入了很多概念比如基于一个业务主体的聚合以及通过聚合根来对外部开放访问,这其实是从业务层面实现了高内聚。

再说说业务层,这个层是对具体应用的包装,比如比如wcf服务、webservice等,通常是具体业务逻辑+调用领域层完成工作;还可以直接调用持久化层,为什么会这样,因为同样是ioc解决了扩展性和耦合性问题。


表现层就是另外一个话题了,比如mvc。

之上的内容得以实现其实完全依赖基础设施层中的IOC和ORM技术。前者解决了各层之间强耦合问题、后者解决了持久化耦合和具体存储依赖的问题。

AOP技术引入又让领域架构从方面解决问题简化了处理逻辑。
所以其实在我看来,领域驱动和三层不矛盾,它是系统架构的一种升级版本,从以实现低耦合、扩展性的架构目标转向对业务的关注。并非它不实现这些目标,而是成熟的ioc技术让之前的目标都不再成为问题,更多的是关注业务和领域。所以领域驱动也更适应技术活业务庞杂,外部服务多的业务场景。

 

posted @ 2018-04-27 19:39  Joseph zheng  阅读(447)  评论(0编辑  收藏  举报