一文一点 | DDD-通用语言、实体、值对象

tech2025-02-03  4

这是【一文一点】的第7篇原创文章,不拘泥于篇幅字数,用一篇文章说清一个知识点。

1、

DDD中的通用语言应该如何理解呢,既然是语言就有基本的名词和动词,其中包的名词:实体对象,对应到生产实际中,比如商品、订单等;其中的动词:领域事件或者命令,比如商品已出库、订单已付款等。

 

为什么要有自己的一门语言呢,我个人认为DDD是一种架构设计方法,为了统一规范大家使用该方法,以便在使用的过程中把所描述的事物统一下来。

 

一方面可以概括生产中的对象,比如现在我们聊的是商品、订单的业务场景,如果换到另外一个商家、促销的业务场景,我们仍然可以说实体对象,业务场景语言描述化得以规范化。

 

另外一方面,可以减少沟通成本,无论在哪个业务场景下,当大家说实体对象的时候,我们仍然可以知道所要描述的是什么。

 

这一点的有点跟设计模式所描述的相同的味道,我指的是在描述上。你想当我们说策略模式的时候,大家一下子就能知道,哦,可以动态的改变定义接口的行为。

 

不过呢,DDD中的通用语言还有个局限性,这个怎么理解,一般语言,我们都会讲到语义环境,有的词可能脱离了语义环境,所表达的意义也许就变了。

 

比如在京东商城,下单的时候,产研管它叫商品,当运输过程中,快递员又管它叫做货物。

 

现实中的这个语义环境对应到DDD里面就是限界上线文。

 

             

图自网络

 

2、

DDD是一种架构设计的方法,在执行的时候又分为战略设计和战术设计。

 

战略设计的时候,我们是站在业务的角度,这个过程我们会产出,建立业务领域模型,划分领域边界,建立我们上面说的通用语言的限界上下文。

 

另外这个过程中确立的界限上下文还可以作为以后微服务设计的参考边界,你会逐渐发现架构设计的深水区往往就是确定边界。

 

战术设计的时候,我们是站在研发的角度,是对战略设计的一个承接,这个过程我们就要侧重于领域模型的技术实现,毕竟所有的架构设计最终都是要靠一行一行的代码落地的。

 

聚合根、实体、值对象、领域服务、应用服务和资源库等代码逻辑都是在这个过程中设计和实现的。

 

3、

上面我们提到所有的设计最终必将有代码来实现,既然先有战略设计,后有战术设计,这样两个过程就会有一个过渡,那么在这个过渡的过程中有两个非常重要的领域对象,实体和值对象。

 

战术设计的目的就是让我们把用户的需求进行实现,并最终产生业务生产数据,保存在数据库中。既然实体和值对象都是这个过程中的重要对象,那么他们的“生命”过程应该也要符合这样的业务过程。

 

             

 

4、

我们先来看实体在这些形态中的反映。

 

实体在业务形态中就是指多个属性和行为的载体,在代码形态中就是包含了属性和方法的类,在运行形态中就是可以被修改的DO(领域对象),在数据形态中就是被映射到数据库的持久化对象。

 

5、

我们再来看值对象的形态反映,在看值对象之前,我们先来理解一下什么是值对象。

 

这里摘录极客时间《DDD实战课》中的一张图,很容易理解,如下。

 

             

 

值对象在业务形态中是指多个属性的【集合】,比如上面这个地址就是省、市、县、街道的集合,不过和实体对象不同的是,虽然都是对象,但值对象不包含业务逻辑,在逻辑上值对象是实体对象的一部分,如上图中,地址是人员的一部分。

 

在代码形态中就是被实体对象对应的类所引用的一个类,比如人员Person这个类,引用了一个地址Address类,另外一种用法也可以是被Person类引用的一个地址的json格式的数据串。

 

在运行形态中值对象就不是实体对象那样,可以把实体对象的某一个属性进行替换,值对象是被整体替换或修改。

 

在数据形态中值对象就是和实体对象的一个具体实例一起被映射到数据对象中,反映到数据库中就是一行数据,而不是,一个主外键关系。

 

6、

这篇文章主要学习了领域驱动设计中的通用语言以及通用语义所受限的语义环境,也就是我们的边界,还学习了实体和值对象,以及它们在业务形态到最终的数据形态中的反映。

 

如果需要更详细的学习DDD知识,可以去极客时间《DDD实战课》。

 

好了,今天又学习了一个知识内容,希望你看到也能对你有点帮助。

最新回复(0)