贫血vs富血
我们来回顾一下。在企业架构模式中,业务层的实现一般有两种模式:一种是事务角本模式(Transaction script),另一种是领域模型模式(Domain Model)。这两种分别对应贫血和富血。好吧,我们不说这些扯淡的东西,我们简单点说。
所谓贫血,就是一个对象里只有属性,如java中的pojo,要实现业务,要依靠service层来实现相关方法,service层的实现是面向过程的,也就是所谓的transaction script.我们现在大量的分层应用action->service->dao->entity的方式就是这种贫血的模式实现。
Java代码
- //贫血代码示例:
- Account.java
- Public class Account{
- private String name;
- private Long num;
- get set…
- }
- AccountService.java
- Public class AccountService{
- public List findAccountBySomething(String abc){}
- public void addAccount(Account a){}
- public void otherBiz(){}
- }
所谓的富血就是属性和方法都封装在Domain Object里,所有业务都直接操作Domain Object。Service层只是完成一些简单的事务之类的,甚至可以不用service层。也就是直接从action->entity.
Java代码
- //富血代码示例
- Account.ava
- Public class Account{
- private String name;
- private Long num;
- public List findAccountBySomething(String abc){}
- public void addAccount(Account a){}
- public void otherBiz(){}
- }
前人总结的一些贫血和富血的对比:
贫血模型的优点:
1.被许多程序员所掌握,许多教材采用的是这种模型,对于初学者,这种模型很自然,甚至被很多人认为是java中最正统的模型。
2.它非常简单,对于并不复杂的业务(转帐业务),它工作得很好,开发起来非常迅速。它似乎也不需要对领域的充分了解,只要给出要实现功能的每一个步骤,就能实现它。
3.事务边界相当清楚,一般来说service的每个方法都可以看成一个事务,因为通常Service的每个方法对应着一个用例。
其缺点为也是很明显的:
1.所有的业务都在service中处理,当业越来越复杂时,service会变得越来越庞大,最终难以理解和维护。
2.将所有的业务放在无状态的service中实际上是一个过程化的设计,它在组织复杂的业务存在天然的劣势,随着业务的复杂,业务会在service中多个方法间重复。
3.当添加一个新的UI时,很多业务逻辑得重新写。例如,当要提供Web Service的接口时,原先为Web界面提供的service就很难重用,导致重复的业务逻辑(在贫血模型的分层图中可以看得更清楚),如何保持业务逻辑一致是很大的挑战。
富血的优点是:
1.领域模型采用OO设计,通过将职责分配到相应的模型对象或Service,可以很好的组织业务逻辑,当业务变得复杂时,领域模型显出巨大的优势。
2.当需要多个UI接口时,领域模型可以重用,并且业务逻辑只在领域层中出现,这使得很容易对多个UI接口保持业务逻辑的一致(从领域模型的分层图可以看得更清楚)。
富血的缺点是:
1.对程序员的要求较高,初学者对这种将职责分配到多个协作对象中的方式感到极不适应。
2.领域驱动建模要求对领域模型完整而透彻的了解,只给出一个用例的实现步骤是无法得到领域模型的,这需要和领域专家的充分讨论。错误的领域模型对项目的危害非常之大,而实现一个好的领域模型非常困难。
3.对于简单的软件,使用领域模型,显得有些杀鸡用牛刀了。
4.对于事务等的处理,如果完全DDD,java支持得不够好。
关于Spring roo
引子中小胖公司就是采用Roo完成DDD富血开发。Spring Roo is a popular open-source rapid application development (RAD) tool for Java developers. ,使用命令行或工具操作来生成自动化项目,操作非常类似于rails。Roo可以很好的支持富血的Java DDD。关于roo我也不想说太多,因为我也没有亲自实战过,大家可以google一下。
如果采用roo,只需要
对于一个业务实现
Java代码
- @Entity
- @RooEntity
- @RooJavaBean
- @RooToString
- public class Employee {
- @NotNull
- @Size(max = 200)
- private String name;
- @Temporal(TemporalType.TIMESTAMP)
- private Date birth;
- }
- //EmployeeController代码如下:
- @RooWebScaffold(automaticallyMaintainView = true, formBackingObject = Employee.class)
- @RequestMapping(“/employee/**”)
- @Controller
- public class EmployeeController {
- }
在这里出现了一行@RooWebScaffold注解,做过rails的人会想,这不是rails里面的scaffold吗错,通过@RooWebScaffold注解,EmployeeController自动获得了curd的所有功能。
好了,就这么简单,一个domain,一个Controller,我们就可以发布到tomcat中运行了
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!