一、引言

这篇博客实际写在 01 之后,但是从内容上应当放在 01 之前,故而我起名为 00。随着对 COLA 框架学习的深入,出现了一对我不理解,但在博文和讨论串中高频出现的词汇——充血模型和贫血模型。本文简单介绍了两者的概念、开发架构的演进以及我的一些思考。

二、正文

2.1 基本概念

2.1.1 贫血模型

在贫血模型中,对象的属性(或者说数据)与行为(或者说业务)是分离。实体类中只包含对象属性和对应的set和get方法,不包含对象的具体行为。MVC架构中的实体类就是典型的贫血模型,对象在流转的过程中只有属性的变化而无具体行为,对数据的操作(业务逻辑)是放在Service层实现的。贫血模型实际不是面向对象编程,而是面向过程编程。

2.1.2 充血模型

在充血模型中,实体类同时包含了对象属性和行为,包括业务逻辑、数据持久化等操作。业务层则只是部分的简单调用逻辑、事务控制、权限控制等。在DDD架构中,充血模型是实体类设计的一种重要方法。充血模型是真正的面向对象编程。

2.2 思考与延伸

在【腾讯云】实现业务逻辑三种方式:事务脚本、贫血模型、DDD中,还提到了事物脚本模式,称MVC模式实为其的延伸,阐述其核心思想就是组成名称的两个词:

  • 事物:实际需要执行的一段原子业务。
  • 脚本:一组原子业务的编排方式,脚本的编排会直接映射到用户的一个行为动作上。
// 用户转账,从一个用户转到另一个用户
public void transactionScript(long accountId, long toAccountId, int amount) {
    dao.reduceAccountBalance(accountId, amount);
    dao.addAccountBalance(toAccountId, amount);
}

给出以上例子的同时,更与更古早的技术存储过程做了比较。顺着这个作者的思路,咱们可以捋一下技术的变迁:

  • 存储过程:由Sql语句和控制语句组成,被封装为一个独立的对象以方便客户端调用,数据与业务逻辑高度耦合;且所有业务逻辑都是在数据库层面,可维护性差;其可能包含的复杂业务逻辑,还可能会导致数据库负载增加,影响数据库性能;
  • 事物脚本模型:由上方的示例可以看出,所有业务逻辑都被放在Dao层中,原本作为一个整体的存储过程脚本被拆分为了一个个粒度更小的原子操作Sql语句,通过编排事物来完成业务,降低了耦合度。
  • MVC架构:把业务逻辑集中在Service层处理,Dao层只做简单数据查询或者持久化,项目的耦合度得到了进一步的降低。
  • DDD架构:实体类同时包含了对象属性和行为,包括业务逻辑、数据持久化等操作。业务层则只是部分的简单调用逻辑、事务控制、权限控制。

可以看到到MVC架构为止,数据与业务逻辑的耦合度都是一步一步降低的。但到了DDD架构,其实体类的设计模式反而让人感觉其耦合度又提高了?具体如何先按下不表,先对本篇范围内的内容做个总结。

三、总结

贫血模型和充血模型概念非常好理解,其区别在于实体类除了属性以外,是否还包含行为。虽然概念很简单,但我们得带着思考学习,除了前文提到的耦合度的疑问,这里提两点来抛砖引玉:

  • 多对象行为类似,导致代码重复。例如对于Player和Monster,都有move这个行为时,要么都加上类似的逻辑,要么继承包含move方法的同一个父类。但假如Player可以move和jump,Monster可以move和run时又该如何呢?
  • 两个不同的对象有交换,业务逻辑应当写在哪。例如对于Player和Monster,是Player.attack(monster),还是Monster.receiveDamage(Player)。

带走疑问与思考,我们走进下一篇,介绍在DDD架构下有着目前为止最佳实践开源Java框架——Alibaba COLA。

四、参考文献

【Github】看了很多架构,发现都没有针对每一层的“DTO”进行设计说明#443

【腾讯云】实现业务逻辑三种方式:事务脚本、贫血模型、DDD

【腾讯云】大白话给你讲清楚之领域模型(贫血模型和充血模型)

【CSDN】什么是贫血模型和充血模型?

【CSDN】禁止使用存储过程

最后修改:2026 年 09 月 14 日
如果觉得我的文章对你有用,请随意赞赏