充血模型中的职责分配
???? 关于充血模型和贫血模型的讨论已经很多了,就不炒现饭了。这里只关注充血模型中的职责分配,因为在设计开发中很容易在这方面出现问题,在充血模型中,一种最极端最常见的情况是将过多的业务逻辑不分青红皂白都放在领域对象中—omain object),导致领域对象太臃肿,违反单一职责原则,很可能引起领域对象不稳定,它本来应该是比较稳定的,可在多个应用中重用。
???? OO设计原则(如单一职责等)和Craig Larman的GRASP(如信息专家)都是用来指导职责分配的,怎么这些在充血模型中就失效了,其实问题最终原因还是设计人员对这些原则没有真正掌握,违背了这些原则。
???? 以处理用例(use case)中客户请求的层次结构为例,采用充血模型后,通常的交互层次是:client-》application service(或application facade、helper对象)-》domain service(或application service直接调domain object)-》domain object。如果采用EJB,那application service很可能就是session bean,不过现在大多数采用POJO。
???? 从上面的层次结构可以看出,业务逻辑可以分布在application service、domain service和domain object这三类之中,显然将过多的业务逻辑分配在domain object是很可能出现问题的。
???? 对这个具体问题,如果我们能明确其分配的具体原则,划分的边界,就基本可以做到逻辑的合理分配。先前提到的OO原则是比较高层的通用的原则。
???? 哪些逻辑放在领域对象中?哪些放在domain service中?哪些放在application service中?
?显然领域对象负责的是领域逻辑,这是一句废话,其实这废话还是有些用处的,对领域逻辑的内涵做下研究,就可得到答案了。领域逻辑应该是该领域对象专有的逻辑,它是不随应用或用例而改变的。例如对某领域中的身份证领域对象,其身份证的验证规则是不变的,身份证总是18位,不管是在哪个应用中,还是哪个用例中,该规则都不变,那很显然这个规则就是身份证领域对象的领域逻辑。再比喻,在银行账号中,如果规定取款金额必须小于余额,这个逻辑不管你的取款流程是什么,不管你是哪个银行应用,都保持不变,那这个就是账号的领域逻辑。可见这也是符合信息专家原则的。如何判断逻辑是不是该领域对象专有的,去问领域专家,他对业务是最清楚的,领域模型其实应该是他负责建模的。领域服务(domain service),这个也类似领域对象,也就是它的逻辑是不随应用或用例而改变的,是该领域专有的,只是其领域逻辑要跨多个领域对象,例如银行转账,涉及到两个领域对象。它一般是起协调或控制作用,类似facade模式。和领域对象一样,也比较稳定。应用服务(application service),分配好了上面两个的职责,这个就比较简单了,剩下的逻辑就基本属于应用逻辑(不管展示层逻辑)。相比而言,应用逻辑(应用服务)是最不稳定的,因为它是应用相关的、用例相关的、会话相关的、处理流程相关的,一般不能重用,每个用例的应用逻辑都不一样。例如某用例中,需要发送短信通知,显然这个不属于领域对象和领域服务,只能是应用逻辑。??????还有一个是基础设施服务,这个还是比较好区分的,例如提供短信发送的服务就是基础设施服务。
?????
??
?
?
????