架构真意:企业级应用架构设计方法论与实践
上QQ阅读APP看书,第一时间看更新

3.3.1 服务、实体与值对象

要将领域模型映射到程序设计,最终都会落实到三种类型的对象设计:服务、实体和值对象。

服务标识的是那些在领域对象之外的操作与行为。在领域驱动设计中,服务通常承担了两类职责:接收用户的请求、执行某些操作。当用户在系统界面中进行一些操作时,就会向系统发出请求。这时,是由服务首先去接收用户的这些请求,然后再根据需求去执行相应的方法,再去操作相应的实体与值对象。最后,当所有操作都完成以后,再将实体或值对象中的数据持久化到数据库中。

接着,就是实体与值对象。在领域驱动设计中,对实体与值对象进行了严格的区分。实体就是那些通过一个唯一标识字段来区分真实世界中的每一个个体的领域对象。例如,在学籍管理系统中的“学员”对象就是一个实体,它通过标识字段“学员编号”将每一个学员进行了区分,通过某个学员编号就能唯一地标识这个学员。并且,这个学员有许多属性,如姓名、性别、年龄等,这些属性也是随着时间不断变化。这样的设计就叫做“实体”。

然而,在领域建模的过程中,还有另外一种领域对象,它代表的是真实世界中那些一成不变的、本质性的事物,这样的领域对象叫做“值对象”。例如地理位置、行政区划、币种、行业、职位,等等。可变性是实体的特点,而不变性则是值对象的特点。例如北京是一个城市,架构师是一个职务,人民币是一个币种,这些特性是永远不变的。

在实际项目中,我们可以根据业务需求的不同,灵活选用实体和值对象。比如,在在线订餐系统中,菜单既可以设计成实体,也可以设计成值对象,关键看业务需求。例如“宫保鸡丁”是一个菜品,如果将其按照值对象设计,则整个系统中“宫保鸡丁”只有一条记录,所有饭店菜单中的这道菜都是引用的这条记录。如果按照实体进行设计,则认为每个饭店的“宫保鸡丁”都是不同的,比如每个饭店的“宫保鸡丁”的价格都不同,因此将其设计成有多条记录,有各自不同的ID,每个饭店都使用自己的“宫保鸡丁”。