背景
- 最近公司开始推行DDD(领域驱动设计),基于充血模型的面向对象开发模式是DDD的特点之一,而在平时开发中我们都使用的是MVC 架构是基于贫血模型的面向过程开发风格,也许有同学就会问了,贫血模型和充血模型是的什么呢?
贫血模型和充血模型
简介
贫血模型:
- 定义对象的简单的属性值,没有业务逻辑上的方法(个人理解)没有找到官方解释
充血模型
- 充血模型也就是我们在定义属性的同时也会定义方法,我们的属性是可以通过某些方式直接得到属性值,那我们也就可以在对象中嵌入方法直接创建出一个具有属性值的对象。也就是说这个对象不再需要我们在进行进一步的操作,这也就复合了OOP的三大特性之一的封装(个人理解)
关于DDD和充血模型的关系
我们在平时进行web开发的时候,就是定义DTO,定义数据库Model,BO等,对其进行get set方法,然后通过service 对Bo对象进行操作,最后通过copy属性持久化数据库和DTO传输。但是如果是充血模型的话,就不用在service进行属性赋值,而是在创建这个对象的时候,进行业务操作,赋予其属性值。这里也就是DDD的思想,这个对象也就是DDD所定义的Entity 或者 value 。Service也就是domianService,由多个Entity 和value 组成,构造最终的领域模型。
下图是作者本人对DDD的理解画的图,也希望能帮到大家理解:
回归正题还是看充血模型和贫血模型
说了这么多DDD思想中的充血模型到底优势在哪里呢?适用于哪些场景呢?而我们都在用贫血模型,但是我们在平时的开发中也没有什么问题呀?
为什么大家都在使用贫血模型?
- 使用贫血模型的传统开发模式,将数据与业务逻辑彻底分离,通过get set方法改变对象属性,对象属性可以随意被修改,这也就如上面所说违反了OOP的三大特性之封装特性。这样的编程方式也就是面向过程的编程方式,面向过程的编程方式是符合人类大脑逻辑的,不用使用太多的设计模式和过多的设计。还有就是在开发中大家经常说的一句及其不负责任的一句话:“怎么方便怎么来”,就一直在堆代码,完全不像以后的可拓展性。也就是说基于贫血模型的编程方式是面向过程编程,人类的思考逻辑方式很符合,在编程过程️也很方便,所以大家都很愿意接受这种编程方式。
- 综上所述:
- 充血模型的设计要比贫血模型更加有难度
- 大家一致使用基于贫血模型的面向过程编程已经成为习惯,比较难转换思想
- 还有就是对代码不负责任的态度。(这是大数程序员的通病吧)
是所有的场景都适合使用充血模型吗?
- 使用充血模型也就是使用基于充血模型的DDD的开发模式,上文也一再强调,充血模型也是定义模式复杂,设计难等,代码开发量也许时其他模型的多,其主要原因还是设计起来难。那就是说如果我们设计一个很简单的业务逻辑,那我们还需要这么复杂的设计思想吗? 并且这个业务在后续的迭代也不变复杂,那我个人认为我们就使用我们的基于贫血模型的面向过程的编程思想。简单的东西何必复杂化呢。这里突然想到我同时讲的一个段子:
- 普通程序员写hello word 直接print
- 高级程序员写hello word 各种设计模式各种可拓展最后输出hello word
- 技术专家写hello word ,直接打印hello word
- 当然我们在进行一个复杂的业务场景,那就需要进行基于充血模型的DDD(领域驱动模型)开发模式了。其实DDD的开发模式也就是充分的遵循OOP发三大特性(或者四大特性,封装,继承,多态,(抽象)),如果是贫血模型的面向过程编程那到最后的结果就是点练成线,由线变成网,密密麻麻不可维护。所以说复杂业务逻辑基于充血模型的进行开发。但是也会是有问题的那就是类膨胀,一个类有很多代码。这个还是可以解决的,那就是通过设计模式,喝业务逻辑细分进行解决。
总结
- 贫血模型和充血模型的简单解释
- 以及DDD开发模式和面向过程编程与充血和贫血模型的关系
- 对比了基于贫血模型的MVC层的面向过程编程范式和基于充血模型的面向对象编程范式的对比
- 两种模型分别适用于那种场景
参考
- https://time.geekbang.org/column/article/169600 设计模式之美
- https://zh.wikipedia.org/wiki/%E5%8F%8D%E9%9D%A2%E6%A8%A1%E5%BC%8F 反面模式
- http://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html DDD的基础理论喝