24

领域驱动设计基本概念答疑

 5 years ago
source link: http://zhangyi.xyz/basic-concepts-of-ddd/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
3M32MbE.jpg!web

本文内容来自我的知识星球「逸派胡言」对群友提出的有关领域驱动设计基本概念的回答。

实体与值对象

问题:DDD实现中领域对象区分实体(Entity)和值对象(Value Object)的目的(Why)是什么?或者换一种问法:领域对象区分实体(Entity)和值对象(Value Object)之后,带来的好处和收益是什么?

回答:从DDD的概念上讲,实体(Entity)与值对象(Value Object)的本质区别仅在于后者无需identity(唯一标识)。这其实就是带来的价值——就是你设计的对象不需要去跟踪和管理这个唯一标识。

这是概念划分上,值对象带来的价值。

再来说设计层面。通常情况下,我们建议将值对象设计成一个不变(Immutable)对象。当一个对象是不变的时,你就基本不需要担心并发带来的诸如同步、冲突等问题了,这既降低了编程的难度,又可以无需引入额外的同步锁影响程序的性能。

反而过来说,之所以可以将值对象设计成不变的,其根本原因还是在于我们无需跟踪和管理唯一标识。

在领域驱动设计中,我们提倡的实践是尽量定义值对象来替代基本类型,原因在于基本类型无法体现统一语言中的领域概念。此外,在多数语言中,我们无法对基本类型做封装,就意味着一个领域概念缺乏领域行为来支持。假设一个实体定义了许多属性,如果这些属性都是基本类型,就会导致与这些属性相关的领域行为都要放到实体中,导致实体的职责变得不够单一。

引入值对象后,情况就不同了,因为我们可以利用合理的职责分配,将这些职责(领域行为)按照内聚性分配到各个值对象中,这个领域模型就能变得协作良好。

当然,反过来说,之所以可以这样设计,还是在于值对象无需承担跟踪和管理唯一标识的职责。

这也是为何Eric要将实体和值对象分开的主要原因,也是值对象给我们带来的价值所在。

Repository与DAO

问题:Repository与DAO其实都是两种模式的名称。然而在领域驱动设计中,名称本身就是非常重要的。Dao即Data Access Object,即数据访问对象。从其命名上看,就应该属于数据访问层,即DDD中的基础设施层。

回答:在DDD中,所有的领域对象应该都属于领域层。那么,该如何访问这些领域对象呢?DDD希望解除领域层与基础设施层之间的关系,即将设计的注意力完全放在领域建模和领域设计上,思考领域逻辑的实现时,应尽可能地不要考虑领域对象的持久化(数据访问),于是就定义了Repository这个抽象。无论放在哪里(文件、DB或者内存),Repository都将其视为一个“资源库”的抽象。经过这么一层的抽象之后,获取领域对象,或者说管理领域对象生命周期的逻辑就应该属于领域层。

在实现上,你当然可以将这样的Repository接口命名为DAO,这本身没有问题,但名不正则言不顺,如果在领域层中夹杂了一个名为DAO的接口,仍然有“将基础设施混入领域层”的嫌疑。

所以,Repository是抽象,代表了对领域对象生命周期的管理,但并不等于是持久化,持久化只是Repository的其中一种实现。你可以假设一台服务器无比的强大,内存大且永远不会宕机,这时何须持久化呢?但无论怎么修改生命周期的具体管理方式,都不会影响到Repository的抽象。

领域服务与应用服务

问题:应用服务与领域服务的区别在哪?

回答:从分层架构上,应用服务属于应用层,领域服务属于领域层。

从职责上看,应用服务只是一个门面(Facade),它具体并不做领域服务的活儿,也就是不提供领域实现,也就是不包含业务逻辑。之所以要引入应用服务,有两个原因:

领域服务或其他领域对象的粒度太细(便于协作、扩展和重用),不利于客户端的调用,基于“最小知识原则”,还是让客户端少知道这些领域对象协作的知识为好。此时的应用服务更像是对领域对象的一种“编排”。

在调用领域对象去完成一个用例时,不可避免地要牵涉到一些属于“横切关注点”的内容,如事务、异常处理、授权认证等。这些横切关注点从职责上看,不属于领域层,放在领域服务中可能会导致对领域逻辑的污染,这些职责就像砌砖墙时需要的水泥。水泥自身不提供砖头的职责,但没有水泥,墙就没法砌起来。

具体对领域服务和应用服务的阐述,可以看我的这篇文章《 一篇文章教你分辨应用服务和领域服务 》。

请关注我的「知识星球」:

v2iqq2j.jpg!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK