贫血模式与充血模式初探

基于业务开发的项目大多是MVC架构的。成为Web项目的标准开发模式,但它却是违反面向对象编程风格的,是面向过程的。之后基于领域驱动设计(Domain Driven Design)开发模式被人提倡。

先搞清楚以下问题: 什么是贫血模型?什么是充血模型? 为什么说基于贫血模型的传统开发模式违反 OOP? 基于贫血模型的传统开发模式既然违反 OOP,那又为什么如此流行? 什么情况下我们应该考虑使用基于充血模型的 DDD 开发模式? MVC 三层架构中的 M 表示 Model,V 表示 View,C 表示 Controller。它将整个项目分为三层:展示层、逻辑层、数据层。MVC 三层开发架构是一个比较笼统的分层方式,落实到具体的开发层面,很多项目也并不会 100% 遵从 MVC 固定的分层方式,而是会根据具体的项目需求,做适当的调整。

现在很多 Web 或者 App 项目都是前后端分离的,后端负责暴露接口给前端调用。这种情况下,我们一般就将后端项目分为 Repository 层、Service 层、Controller 层。其中,Repository 层负责数据访问,Service 层负责业务逻辑,Controller 层负责暴露接口。只要是依赖数据库开发的 Web 项目,都差不多。

将数据与操作分离,只包含数据,不包含业务逻辑的类,就叫作贫血模型(Anemic Domain Model)。它破坏了面向对象的封装特性,是一种典型的面向过程的编程风格。

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

领域驱动设计,即 DDD,主要是用来指导如何解耦业务系统,划分业务模块,定义业务领域模型及其交互。领域驱动设计这个概念并不新颖,早在 2004 年就被提出了,到现在已经有十几年的历史了。不过,它被大众熟知,还是基于另一个概念的兴起,那就是微服务。

微服务除了监控、调用链追踪、API 网关等服务治理系统的开发之外,还有另外一个更加重要的工作,那就是针对公司的业务,合理地做微服务拆分。而领域驱动设计恰好就是用来指导划分服务的。所以,微服务加速了领域驱动设计的盛行。

做好领域驱动设计的关键是,看你对自己所做业务的熟悉程度,而并不是对领域驱动设计这个概念本身的掌握程度。不要把领域驱动设计当银弹,不要花太多的时间去过度地研究它。

实际上,基于充血模型的 DDD 开发模式实现的代码,也是按照 MVC 三层架构分层的。Controller 层还是负责暴露接口,Repository 层还是负责数据存取,Service 层负责核心业务逻辑。它跟基于贫血模型的传统开发模式的区别主要在 Service 层。

基于贫血模型的传统的开发模式,重 Service 轻 BO;基于充血模型的 DDD 开发模式,轻 Service 重 Domain(领域模型)。

贫血模型为什么会被广大程序员所接受呢? 1.大部分情况下,开发的系统业务可能都比较简单,简单到就是基于 SQL 的 CRUD 操作,所以,根本不需要动脑子精心设计充血模型,贫血模型就足以应付这种简单业务的开发工作。 2.充血模型的设计要比贫血模型更加有难度。 3.思维已固化,转型有成本。

开发有哪些区别呢?

首先,贫血模式:接到一个后端接口的开发需求的时候,就去看接口需要的数据对应到数据库中,需要哪张表或者哪几张表,然后思考如何编写 SQL 语句来获取数据。之后就是定义 Entity、BO、VO,然后模板式地往对应的 Repository、Service、Controller 类中添加代码。

业务逻辑包裹在一个大的 SQL 语句中,而 Service 层可以做的事情很少。SQL 都是针对特定的业务功能编写的,复用性差。当要开发另一个业务功能的时候,只能重新写个满足新需求的 SQL 语句,这就可能导致各种长得差不多、区别很小的 SQL 语句满天飞。

相反,应用基于充血模型的 DDD 的开发模式,那对应的开发流程就完全不一样了。在这种开发模式下,我们需要事先理清楚所有的业务,定义领域模型所包含的属性和方法。领域模型相当于可复用的业务中间层。新功能需求的开发,都基于之前定义好的这些领域模型来完成。

越复杂的系统,对代码的复用性、易维护性要求就越高,就越应该花更多的时间和精力在前期设计上。而基于充血模型的 DDD 开发模式,正好需要前期做大量的业务调研、领域模型设计,所以它更加适合这种复杂系统的开发。

你可能感兴趣的:(贫血模式与充血模式初探)