10-11 | 设计模式之美——王争

一直贫血而不自知

10 | 理论七:为何说要多用组合少用继承?如何决定该用组合还是继承?

01 | 为什么不推荐使用继承?

  • 继承层次过深、继承关系过于复杂会影响到代码的可读性和可维护性。

02 | 组合相比继承有哪些优势?

  • 继承主要有三个作用:表示 is-a 关系,支持多态特性,代码复用。而这三个作用都可以通过组合、接口、委托三个技术手段来达成。除此之外,利用组合还能解决层次过深、过复杂的继承关系影响代码可维护性的问题。

03 | 如何判断该用组合还是继承?

  1. 类之间的继承结构稳定(不会轻易改变),继承层次比较浅(比如,最多有两层继承关系),继承关系不复杂,我们使用继承。反之,系统越不稳定,继承层次很深,继承关系复杂,我们就尽量使用组合来替代继承。
  2. 设计模式会固定使用继承或者组合:比如,装饰者模式、策略模式、组合模式等都使用了组合关系,而模板模式使用了继承关系。
  3. 特殊场景必须使用继承:例如:FeignClient 是一个外部类,我们没有权限去修改这部分代码,但是我们希望能重写这个类在运行时执行的 encode() 函数。这个时候,我们只能采用继承来实现了。

04 | 课堂讨论

  • 我们在基于 MVC 架构开发 Web 应用的时候,经常会在数据库层定义 Entity,在 Service业务层定义BO(Business Object),在 Controller 接口层定义 VO(View Object)。大部分情况下,Entity、BO、VO 三者之间的代码有很大重复,但又不完全相同。我们该如
    何处理 Entity、BO、VO 代码重复的问题呢?
  • 答:
    1. Entity, Bo, Vo三者之间,显然并不存在 is-a关系,首先排除使用继承。
    2. 其次三者间也并非是严格的has-a关系,half measure之一是考虑使用组合(composition) + 委托(delegation)的方式解决代码重复的问题,但并不是我心中的最佳答案.
    3. 我的答案是不解决三者间的代码重复问题。Value Class就只是Value Class, 代码重复并不是业务上的代码重复,那就让它重复吧.


11 | 实战一(上):业务开发常用的基于贫血模型的MVC架构违背OOP吗?

01 | 什么是基于贫血模型的传统开发模式?

  • 贫血模型(Anemic Domain Model): 只包含数据,不包含业务逻辑的类。==》面向过程

02 | 什么是基于充血模型的 DDD 开发模式?

  • 什么是充血模型?
    1. 充血模型(Rich Domain Model):数据和对应的业务逻辑被封装到同一个类中。是典型的面向对象编程风格。
  • 什么是领域驱动设计( DDD)?
    1. DDD:指导如何解耦业务系统,划分业务模块,定义业务领域模型及其交互。
    2. DDD 开发模式也是按照 MVC 分层的,基于贫血模型的传统开发模式的区别主要在 Service 层。
    1.基于贫血: 重 Service 轻 BO
    	Service层 :Service 类+ BO 类,
    	BO 只包含数据,不包含具体的业务逻辑。
    	业务逻辑集中在 Service 类中。
    	
    2.基于充血模型的 DDD: 轻 Service 重 Domain
    	Service层 :Service 类+ Domain 类
    	Domain 就相当于贫血模型中的 BO。
    	但是Domain包含数据以及业务逻辑
    

03 | 为什么基于贫血模型的传统开发模式如此受欢迎?

  1. 业务简单,贫血模型够用,即使设计出领域模型也会比较单薄,跟贫血模型差不多,没有太大意义。
  2. 充血模型的设计要比贫血模型更加有难度。
  3. 思维已固化,转型有成本。

04 | 什么项目应该考虑使用基于充血模型的 DDD 开发模式?

  • 业务复杂的系统开发:包含各种利息计算模型、还款模型等复杂业务的金融系统。

05 | 课堂讨论

  • 对于我们举的例子中,UserEntity、UserBo、UserVo 包含的字段都差不多,是否可以合并为一个类呢?
  • 基本上经历过的web项目都是基于贫血模型开发模式的,entity,bo,vo不能放在一个类里,每个对象的应用场景不同,entity是映射数据库字段的,bo,vo适合业务和展示相关的,而且entity相对来讲变化不多,bo,vo可能会频繁变化,所以不适合放在同一个类里。

版权声明:本文为qq_43619459原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。