关于贫血模型

关于贫血模型
贫血模型的问题与所谓专家原则以及分层原则直接相关。面向对象系统的主要任务就是安排对象系统的责任划分以形成合理的协同关系;专家原则是说,某个功能、行为应该分配给持有相关信息最完整的对象;显然,专家原则与关于高内聚的思想相一致。分层原则是就系统的大结构而言,企业级应用以业务逻辑为中心,向下是持久层,向上是表现层。

设计原则的适用要考虑具体的条件,这是软件系统设计的本质。抽象地来看,专家原则与分层原则存在矛盾:按照分层原则,系统会出现许多对象位于不同的层:持久层对象是所有数据的来源,那么教条地套用专家原则会得出这样的结论:既然持久层的PO拥有完备的数据(信息),它自然应该做所有的事情,包括相关逻辑以及渲染。这显然不合理。实际上基本合理的安排是:分层原则导致出现不同的层中的对象群;专家原则主要是在业务逻辑层,适用于主要以功能为特征、具有丰富的外部行为的功能性对象,而不适用于实体Bean这样的东西;后者是一种信息结构,Getter和Setter不能够作为某种行为,甚至有人主张干脆将成员置为Public。

由此可见,分层应该是软件系统宏观的构造规律和原则,专家原则则要微观一些。认识和把握这一点比之原则本身更为重要。体系结构之所以被称为Art,与这种变化、变通的准确把握有关。

所谓对贫血模型的指责也就是对机械地分层的某种后果的批判。其实,抽象地谈论某种设计原则的是是非非几乎肯定没有意义,事情的实质仍然在于条分缕析地界定出各自的约束条件、适用条件。

首先一点是,不能够过分地无视分层原则,这是软件系统构造迄今为止最广泛适用的原则之一。其次,关于对象的行为,我们起码可以给出一个最基本的划分:

对象本身所固有的、内在的、使其成为它自己的行为,这些行为是对象定义的一部分。它们高于对象的Getter和Setter,但仍然属于基础行为。
基于对象的第一类行为集合,需要对象与其它对象协同工作才能够完成的动作
就实现层面上也有一个划分:
对象完成这个行为并不需要依赖于某种狭隘的技术就可以完成。比如它的某些成员经过数学运算之后的一个结果。
与之相反,对象完成这个行为需要依赖于某种狭隘的技术才可以完成,比如某种渲染,需要依赖于不同的GUI表现方式。
有了这个基本划分,很自然地,如果符合两类划分中的第一种划分,可以考虑将这些行为注入对象,为实体bean充血。当然,以上的做法并不是给出了一个解决此类矛盾的灵丹妙药,不同的条件下仍然有其它的做法会比较合适。比如对于第一种划分中的第一类对象,一个对象处理器(EntityHandler)可能很好地解决问题,handler本身形成一个具有抽象层次的体系来处理对象共有的以及特殊的行为,但它们基本上不涉及对象之间需要高度配合才能完成的事情,那些事情由更上层的组合逻辑才能够完成。Handler是实体的外部相对单纯的专门的操作者,它们与对象的关系非常紧密以至于运行时与实体成对存在;我们可以认为它们处于逻辑层的底部,紧贴持久层之上。