和平相处
所以不论是贫血模型还是充血模型,他们各有优缺点,到底应当采用贫血模型还是冲血模型。争执了这么多年,但我认为他们并不是熊掌和鱼的关系。
我们应当把它们结合起来,取长补短,合理利用。关键是要先弄清楚他们的差别,也就是业务逻辑应当在哪里实现评选模型的业务逻辑在service 中实现。但充血模型是在领域对象中实现清楚了这一点。在今后的软件设计时,可以将那些需要封装的业务逻辑放到领域对象中,按照充血模型去设计除此之外的其他业务逻辑放到service 中,按照贫血模型去升级。那么哪些业务逻辑需要封装起来,按照充血模型设计呢?这个仁者见仁智者见智。
充血模型使用场景
- 如前所述,如果在领域模型中出现了类似继承多态的情况,则应当将继承与多态的部分,以充血模型的形式在领域对象中实现。
- 如果在软件设计的过程中,需要将一些类型或者编码进行转换,则将转换的部分封装在领域对象中。例如一些布尔类型的字段在数据库中是没有布尔类型的。不同人的习惯不同,有的人习惯采用零和一,有的人习惯采用y 和n 或者t 和f 这样就会给上层开发人员诸多的困惑。到底哪些字段是y 和n 哪些是t 和f 这时就可以将它们封装在领域对象中,然后转换为布尔类型,展现给上层开发,按充血模型来设计。
希望在软件设计中能更好的表现领域对象之间的关系。比如在查询订单的时候,想要显示每个订单对应的用户,以及每个订单包含的订单明细。这时除了要将领域模型中的关系体现在领域对象的设计外,还要有仓库与工厂的支持。如装载订单时,需要同时查询订单和订单明细,并通过订单工厂装配查询订单以后需要通过工厂填补相应的用户与明细。
- 最后一种情况被称为聚合,也就是在真实世界中,那些代表整体与部分的事物。比如在订单中有订单和订单明细,一个订单对应多个订单明细。从业务关系来说,他们是整体与部分的关系。订单明细是订单的一个部分。没有了这张订单,他的订单明细就没有任何意义了。这时我们在操作订单的时候,就应当将对订单明细的操作封装在订单对象中,按照冲选模型的形式进行设计。
后记
基于ddd的程序设计领域模型分析,只是软件需求分析的中间过程,它最终需要落地到程序设计领域。模型的最终落地是三种类型的对象。
服务,实体与值对象,而设计思路有两种。贫血模型与充血模型,通过这样的落地领域模型就能很好的指导程序开发,提高设计质量。在ddd落地的过程中,不必过于纠结到底是实体还是值对象。应当将更多的精力集中于对业务的分析与理解。同时,将贫血模型与充血模型结合起来,取长补短,合理编码。
然而,领域模型的落地还有诸多难题需要解解决。后面继续介绍ddd 的聚合,仓库与工厂及其设计思路。
网友评论