首页 > 技术文章 > 领域驱动设计之实体、值对象、领域服务

malaoko 2015-11-24 23:23 原文

建立领域模型的第一步就是需要识别出实体、值对象与领域服务。

一.实体

1.实体是领域中需要唯一标识的领域概念。通常在业务中,需要唯一标识与区分的对象并需要持续对它进行跟踪,这样的对象我们认为是实体。这里的唯一标识通常指的是业务上的唯一标识,比如订单号、雇员工号等信息,而不是数据库中因为技术需要存储的自增int id或Guid列。

2.如果两个实体所有状态都一样,但如果标识不一样,就是两个不同实体。比如订单对象就应该是实体,就算两个订单的订单日期、订单总额等信息都一样,只要标识不一样,比如订单号,我们就认为它们是不同的实体。

3.实体只保留必要的属性与行为。比如一个客户实体应该保留客户的基本信息,但像国家、省、城市、街道等信息联合表示一个完整的概念,这种完整的概念应该迁移到其他实体或值对象上,这样有助于客户实体的理解和可维护性,并明确了清晰的职责。

 

二.值对象

1.值对象是领域中不需要唯一标识的领域概念,通常在业务中,我们不需要区分对象是哪一个,而只关心对象是什么,这样的对象我们认为是值对象。

2.如果两个对象所有状态都一样,我们就认为是同一个值对象,比如地址信息、订单状态信息等。

3.值对象是只读的,具有不变性不能直接修改,但可以被替换。如果我们要修改一个客户的街道信息,应该是Customer.Address address=new Address();address.Street=;而不应该是Customer.Address.Street=;

 

三.领域服务

1.某些业务行为不好归于某个实体或值对象时,可以把它们归与领域服务这种对象。

2.领域服务本质上就是一些操作,不包含状态,通常用于协调多个实体。比如借书领域中,账户、书与借书信息分别是三个实体(实际上分别是三个聚合的聚合根,聚合与聚合根后面文章再详细描述),借书的这个行为归于其中任何一个实体都不合适,虽然有一种认为是在账户实体上实现借书行为,将书作为参数传递给账户,并在方法中操作借书信息,但因为在账户聚合根上要使用到其他两个聚合根,建议还是通过领域服务进行协调。并且通过领域服务进行协调,还可以保证不同聚合的一致性(比如一个借书信息产生后,相关书的总数信息就减少1,同时账户所借书的总数上加1)。

3.领域服务可以直接暴露给应用层,这样可以有效的保护领域模型。

4.DDD中定义了三种服务:应用层服务、领域服务、基础服务。

 

欢迎加入QQ讨论群:309287205

 

推荐阅读