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

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

实体与值对象  


问题: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),它具体并不做领域服务的活儿,也就是不提供领域实现,也就是不包含业务逻辑。之所以要引入应用服务,有两个原因:

  • 领域服务或其他领域对象的粒度太细(便于协作、扩展和重用),不利于客户端的调用,基于“最小知识原则”,还是让客户端少知道这些领域对象协作的知识为好。此时的应用服务更像是对领域对象的一种“编排”。
  • 在调用领域对象去完成一个用例时,不可避免地要牵涉到一些属于“横切关注点”的内容,如事务、异常处理、授权认证等。这些横切关注点从职责上看,不属于领域层,放在领域服务中可能会导致对领域逻辑的污染,这些职责就像砌砖墙时需要的水泥。水泥自身不提供砖头的职责,但没有水泥,墙就没法砌起来。


相关文章
|
7月前
|
Python
面向对象编程:核心概念与实践
面向对象编程:核心概念与实践
106 0
|
7月前
|
领域建模
架构设计 DDD领域建模 核心概念
【1月更文挑战第6天】架构设计 DDD领域建模 核心概念
|
前端开发 Java 数据库连接
领域驱动设计:从学习到实践(一)
产品同学将需求分析完和开发同学进行需求评审,评审完毕后开发同学开始基于需求进行设计,一般会落到数据库设计,将库表设计完毕后,再向上进行分层开发。如果是前后端分离的项目,会在前期约定接口,进行基于契约的并行开发。所以,我们称这种方式为数据驱动开发,或基于数据模型的开发。
领域驱动设计:从学习到实践(一)
|
存储 自然语言处理 前端开发
领域驱动设计(DDD)-基础思想
一、序言     领域驱动设计是一种解决业务复杂性的设计思想,不是一种标准规则的解决方法。在领域驱动设计理念上,各路大侠的观点也是各有不同,能力有限、欢迎留言讨论。 二、领域驱动设计 DDD是什么 wiki释义:     领域驱动设计(英语:Domain-driven design,缩写 DDD)是一种通过将实现连接到持续进化的模型[1]来满足复杂
7545 0
|
26天前
|
存储 设计模式 数据可视化
DDD新手入门:领域模型设计的七个核心概念
小米,29岁程序员,分享领域模型落地知识。文章解析领域、子域、限界上下文、领域对象、聚合、工厂与仓库等概念,助你理解领域驱动设计。
57 1
|
7月前
|
设计模式 开发框架 算法
C++中的设计模式:基本概念与应用
C++中的设计模式:基本概念与应用
73 2
|
7月前
|
设计模式 存储 缓存
第三篇 结构型设计模式 - 简化复杂系统的结构
第三篇 结构型设计模式 - 简化复杂系统的结构
|
测试技术 微服务
领域驱动设计的基本概念有那些
领域驱动设计的基本概念有那些
|
消息中间件 架构师 搜索推荐
DDD领域驱动设计的概念解析
DDD领域驱动设计的概念解析
248 1
|
设计模式 算法 关系型数据库
设计模式——设计模式简介、分类及面向对象设计原则
23 种设计模式中有些模式今天已经不流行了,有些模型已经被语言机制替代了,有些模式你可能常常会忘记,但这些都不重要,重要的是设计原则,因为有了这些设计原则,你有可能发明自己的模式,你也可以理解未来千千万万其他领域的模式。
104 1