贫血模型最早广泛应用是源自于EJB2,最强盛时期则是由Spring创造,把“行为”(也称为逻辑、过程)和“状态”(可理解为数据,对应到语言就是对象成员变量)分离到不同的对象之中,那个只有状态的对象就是所谓的“贫血对象”(常称为VO——Value Object),而那个只有行为的对象就是我们常见的N层结构中的Logic/Service/Manager层(对应到EJB2中的Stateless Session Bean)。(曾经Spring的作者Rod Johnson也承认,Spring不过是在沿袭EJB2时代的“事务脚本”,也就是面向过程编程)
充血模型其实很简单,就是面向对象设计的本质:“一个对象是拥有状态和行为的”,比如说一个人,他眼睛什么样鼻子什么样这就是状态,人可以去打游戏或是写程序,这就是行为。为什么要有一个“人Manager”这样的东西存在去帮人“打游戏”呢?
举个简单的J2EE的例子,设计一个与用户(User)相关的功能,传统的设计一般是:
类:User+UserManager
保存用户调用:userManager.save(User user);
充血的设计则可能会是:
类:User
保存用户调用:user.save();
——User有一个行为是:保存它自己
其实它们没有什么特别适用的方向,个人更倾向于总是使用充血模型,因为面向对象编程总是比面向过程编程要有更丰富的语义、更合理的组织、更强的可维护性——当然也更难掌握一些。因此实际工程场景中,是否使用,如何使用还依赖于设计者以及团队充血模型设计的理解和把握,因为现在绝大多数J2EE开发者都受贫血模型影响非常深。
另外,实际工程场景中使用充血模型还会碰到很多很多细节问题,其中最大的难关就是“如何设计充血模型”或者说“如何从复杂的业务中分离出恰到好处且包含语义的逻辑放到VO的行为中”,因为以我的经验来看,不特指谁,大多数J2EE开发者其实面向对象都还没有入门,不过这个已经超出了当前贴的问题:)