DDD中的分层

大多数具有重要业务和技术复杂性的企业应用都定义了多个层级。层级是一种逻辑体,与服务的部署无
关,它们的存在是为了帮助开发人员管理代码复杂性。不同层(如领域模型层和表现层等)可能有不同
类型,因此在这些类型间需要转义。
例如,一个实体可能从数据库中加载,随后实体的部分信息或包含其他实体额外数据的信息聚合,能通
过 REST Web API 发送到客户端 UI。这里的要点是领域实体包含在领域模型层内部,并且不应传送到不
属于它的其他区域,比如表现层。
此外,需要由聚合根(根实体)控制的始终有效的实体(详见“设计领域模型层的验证”一节),因此
实体不应该与客户端视图绑定,因为在 UI 层级的某些数据可能未经验证。这就是 ViewModel 的用武之
地,ViewModel 是一个仅为满足表现层需要的数据模型。领域实体不直属于 ViewModel,相反,需要
在 ViewModel 和领域实体之间相互转换
当应对复杂性时,重点是要有一个由聚合根(稍后会详细介绍)控制的领域模型,以确保与该组实体
(聚合)相关的所有不变量和规则都通过一个单独的入口点或门来进行,这就是聚合根。
 
这里我们可以参考下微软开源项目eShopOnContainers 应用中是如何实现分层设计的。

假设想设计系统以便每一层只与特定的其他层进行通信,强制将这些层作为不同类库来实现会更容易,
因为能清晰地识别类库间有哪些依赖。例如,领域模型层不应该依赖于其他任何层(领域模型类应该是
普通的 CLR 对象,或称为 POCO 的类)。如图所示,Ordering.Domain 类库仅依赖.NET Core 的库
或 NuGet 包,而没有依赖任何其他自定义库(数据层类库,持久化库等等)。
领域模型层:负责表达业务概念、业务状态信息及业务规则。尽管保存业务状态的技术细节是由基
础设施层实现的,但反映业务情况的状态是由本层控制并使用的,领域模型层是业务软件的核心。
 
根据持久化透明和基础架构透明原则,该层必须完全忽视数据持久化的细节,这些持久化任务应该在基
础架构层完成。因此该层不应直接依赖基础架构层,这意味着一个重要规则:领域模型实体类应该是
POCO。
领域实体不应对任何数据访问基础框架,如 Entity Framework 或 NHibernate 有任何直接依赖。理想情
况下,领域实体不应该继承自或实现任何基础框架里的任何类型。
大多数现代的 ORM 框架,如 Entity Framework Core 允许使用这种方式,因此领域模型类不会与基础
架构耦合。然而在使用某些 NoSQL 数据库和框架时,使用 POCO 实体也是可行做法,如 Azure Service
Fabric 里的 Actors 和 Reliable 集合。
虽然为领域模型遵守持久化透明原则很重要,但也不应忽略持久化问题。理解数据的物理模型和如何映
射到实体对象模型依然很重要,否则设计就无法实现。
另外,这也并非意味着可以将为关系型数据库设计的模型直接移动到 NoSQL 或面向文档的数据库中。
对于某些实体模型也许可以这么做,但通常是不行的。此外也有一些实体模型必须遵守同时来自于存储
技术和 ORM 技术的约束条件。
应用层
对于应用层,可以再次引用 Eric Evans 的《领域驱动设计》:
应用层:定义软件要完成的任务,并指挥表达领域概念的对象来解决问题。这一层所负责的工作对
业务来说意义重大,也是与其他系统的应用层进行交互的必要渠道。应用层要尽量简单,不包含业
务规则或知识,而只为下一层中的领域对象协调任务,分配工作,使它们互相协作。它没有反映业
务情况的状态,但却可具有另一种状态,即为用户或程序显示某个任务的进度。
.NET 中的微服务应用层通常使用 ASP.NET Core Web API 项目来实现,包括微服务的交互、远程网络访
问和从界面或客户端应用发起的外部 Web API 调用。它还包含使用 CQRS 方法时的查询、微服务接受
的命令以及微服务间的事件驱动通信(集成事件)。表示应用层的 ASP.NET Core Web API 必须不包含
业务规则或领域知识(尤其是事务或更新的领域规则),这些内容应该由领域模型类库所拥有。应用层
必须仅协调任务而不能保留或定义任何领域状态(领域模型)。应用层将业务规则的执行委托给领域模
型类本身(聚合根或领域实体),最终在那些领域实体中更新数据。
基本上,应用逻辑是实现基于特定前端的所有用例的地方,例如与 Web API 服务相关的实现。
这样做地目的在于,在领域模型层中的领域逻辑,包括不变量、数据模型和相关业务规则必须完全独立
于表现层和应用层。最重要的是领域模型层必须不能直接依赖任何基础架构框架。
基础架构层
基础架构层用于将最初保留在(内存中)领域实体中的数据持久化到数据库或其他持久存储中。例如使
用 Entity Framework Core 实现的仓储模式类将 DBContext 数据持久化到关系型数据库中。
根据前文提到的持久化透明和基础架构透明原则,基础架构层绝对不能“污染”领域模型层。我们必须
在绝对不产生框架强依赖的前提下确保领域模型实体类和用来持久化数据(EF 或任何其他框架)的基
础架构无关。领域模型层类库应该只有领域代码,即仅有实现软件核心的 POCO 实体类,并且与基础
架构技术完全解耦。

 

原文地址:https://www.cnblogs.com/qinwei/p/6437721.html