设计原则与思想: 实战一(上)

137 阅读4分钟

引言:

业务开发常用的基于贫血模型的MVC架构违背OOP吗?

MVC三层架构是一种基于贫血模型的开发模式, 虽然已经成为标准的web开发模式, 但它违反了面向对象编程风格, 是一种面向过程编程风格, 被人称为: 反模式

当领域驱动设计(Domain Driven Design, 简称DDD)盛行后, 传统的开发模式更加被人诟病. 下面结合"虚拟钱包"的开发案例, 来弄清楚这2种开发模式

本节需要搞清楚下面几个问题

  1. 什么是贫血模型? 什么是充血模型?
  2. 为什么基于贫血模型的传统开发模式违反的OOP?
  3. 基于贫血模型的传统开发模式既然违反了OOP, 那又为什么如此流行?
  4. 什么情况下我们应该考虑使用基于充血模型的DDD开发模式?

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

1.1 回顾MVC三层架构

MVC三层架构中的M标识Model, V表示View, C表示Controller. 它将整个项目分为三层: 展示层, 逻辑层, 数据层. 在前后端分离的项目中, 后端一般分别为: Repository层, Service层, Controller层.

1.2 什么是贫血模型?

平时开发web后端项目时, 由UserEntity和UserRepository组成数据访问层, UserBO和UserService组成业务逻辑层, UserVO和UserController组成接口层.

我们可以发现UserBO是一个纯粹的数据结构, 里面只包含数据, 不包含任何业务逻辑, 业务逻辑都集中在UserService中. Service层的数据和业务被分割为: BO和Servcie, 那么像这种只包含数据, 不包含业务逻辑的类就叫做: 贫血模型(Anemic Domain Model).

这种破坏了面向对象的封装特性, 是一种典型的面向过程的编程风格.

二. 什么是基于充血模型的DDD开发模式?

目前它是一种被推崇的开发模式

2.1 什么是充血模型?

在贫血模型中, 数据和业务是分散在2个不同的类中, 充血模型(Rich Domain Model)正好相反, 数据和业务逻辑被封装在一个类中, 满足面向对象的封装特性, 是一种典型的面向对象编程风格.

2.2 什么是领域驱动设计?

领域驱动设计: 即DDD, 主要用来指导如何解耦业务系统, 划分业务模块, 定义业务领域模型及交互.

在基于贫血模型的传统开发模式中, Service层包含Service类和BO类两部分, BO是贫血模型, 只包含数据, 不包含业务逻辑, 业务逻辑都集中在Service类中.

在基于充血模型的DDD开发模式中, Service层包含Service类和Domain类两部分, Domain相当于BO, 不过跟BO不同的是, Domain既包含数据, 也包含业务逻辑, 而Service类变得非常单薄

总结:

(1) 基于贫血模式的开发模式, 重Service, 轻BO; (2) 基于充血模式的开发模式, 重Domain, 轻Service;

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

  1. 大部分情况下, 系统业务比较简单, 不需要精心设计充血模型, 贫血模型就足以应付
  2. 充血模型比贫血模型更加有难度, 需要设计好对数据的暴露, 定义好业务逻辑等
  3. 思维固化, 转型需要成本.

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

基于贫血模型的传统开发模式, 适合业务简单的系统开发.

基于充血模型的DDD开发模式, 适合业务复杂的系统开发.

它们俩除了一个是业务放在service层中, 一个业务放在Domain领域模型中, 还是一个非常重要的区别, 就是开发模式.

基于DDD的开发模式, 首先要理清所有的业务, 才能定义领域模型中所包含的属性和方法.日后维护起来, 都在各自的领域模型中, 可维护性更高.所以越复杂的系统更适合充血模型的DDD开发模式.

五.课堂讨论

  1. UserEntity, UserBo, UserVO包含的字段都差不多, 是否可以合并为一个类呢?

不行, 各层之间的数据模型不要共用, 因为各自的稳定性不同.各层数据模型变更原因和速率都不同, 离IO设备越近, 稳定性越差. 比如说: controller层的VO, rep层的entity. Domain层的数据稳定性是最高的.