现在的问题
现在我们J2EE开发碰到了什么问题呢? 让我们想象一下使用Spring和Hibernate开发一个J2EE WEB应用是什么样的:我们需要增加一个新的域对象类型为Person,下面主要的开发步骤:
- 创建
Person
类. - 创建
PersonDAO
类. - 创建
Person数据表
. - 定义
PersonDAO在
Spring的application context XML文件. - 创建
Person
page页面和action类. - 增加
Person页面到
web框架(如struts)XML配置文件中. - 创建
personList
页面来显示Person实例
. - 创建
personEdit
页面来编辑Person
实例.
你会确实感慨:真是需要很多步骤啊。
如何解决?
关键问题是我们开发时不能重复一些步骤,因此必须尽量减少步骤,如果只减少步骤到:
- 创建
Person
类?
是否只需要第一个步骤就可以?在第一步时,我们花费更多时间精力进行域建模,确定域模型的属性行为等。其他步骤我们会发现下面的规律:
- 对于每个实体,我们需要完成应用的基本功能,如 create, retrieve, update, and delete (CRUD).
- 我们需要每个实体持久化到数据库.
- 我们需要数据库为每个实体创建数据表。
- 我们需要安排实体之间的关系。
当然,在复杂应用中,不会只是这些功能,但是如果我们将这些功能通过框架实现,将大大提高我们的开发效率。
域驱动开发
域驱动开发(domain driven development framework ),简称DDD是一种最新的OO设计概念,它是由ROR和Naked Object组织提出的。
所谓naked Object是指一个复杂的域对象,这个Object是一个POJO,但是不是一个傻傻的完全是属性的POJO,而是封装了业务逻辑的POJO,注意这里是最大的区别,一般业务逻辑我们是通过另外的Service类来实现,然后在Service中封装的transaction script(Martin Fowler却称为贫血模型) , naked Object则是合并起来的(有的类似回归传统了,符合Martin Fowler审美观了),但是,这种纯OO是和SOA()思想矛盾的(Service-Oriented vs. Object-Oriented ),可见Adventures in SOA(puts the business logic in service-like methods instead of on the object, service method -> business method --> persistence method) )
个人感觉整个软件好像一直在玩0或1的游戏,不过也许最复杂的体系就是来自最简单的抉择,如股票/汇市等投资领域也如此。
naked Object提出现在J2EE开发和裸体对象DDD开发下的图:
通过这张图我们可以看到,以前方式造成J2EE开发层次之间调用混乱,修改和拓展非常不方便,而在右边的DDD开发方式下,界面(边界)对象就是域对象就是持久化的实体BO,没有多余的Contorller或Action了。原来Domain层被服务层Service layer遮挡,在右图中,则Domain层直接暴露给前台了,所以Domain没有东西被遮盖,裸露了,称为Naked(裸露) Objects.
现在怎么办?
ROR提倡的DDD方式引起了众多J2EE开发者的兴趣,在各大Java媒体正在引起广泛的讨论,但是ROR不是Java的,那么有无基于Java的DDD开发框架呢?
目前有不少DDD开发框架正在诞生中,Jdon框架正是在ROR这种精神指引下的一款快速开源开发框架,Jdon框架1.2.2版本虽然不是一个完全意义上的Naked Object,基于Service-Oriented 架构,但是已经初步具备上图右边开发流程,具体可参考Jdon Sample的开发流程
使用Jdon框架开发J2EE应用系统,最重要的一个前提是:设计好你的域对象,然后在将域对象复制到表现层,变成表现层的ActionForm/ModelForm;将域对象直接在持久层使用Hibernate/iBatis等持久化到数据库;如果使用EJB的实体Bean持久化技术,将无需实现建立数据表;应用系统部署时,J2EE容器将直接根据实体建立数据表,也可节省前面步骤中两个步骤。
当然,目前Jdon框架是采取分离手法,遵循桥模式,将抽象和行为分离,每个域对象对应一个操作它的服务类或DAO类,服务类主要用来封装业务逻辑层,然后将业务Service作为一个业务组件暴露给表现层的Controller/Action类,而Controller/Action则无需代码,只要通过如下配置即可完成:
<model key="username" class="com.jdon.framework.samples.jpetstore.domain.Account">
<actionForm name="accountForm"/> //指定边界类
<handler>
<service ref="accountService"> //指定某个业务接口
<getMethod name="getAccount"/>
<createMethod name="insertAccount"/> //业务接口的新增方法
<updateMethod name="updateAccount"/> //业务接口的修改方法
<deleteMethod name="deleteAccount"/>
</service>
</handler>
</model>
通过上述配置,净化了上图中应用控制层(Application or Controller layer)和Domain Layer之间对应关系,变得有条理而且明晰。
随着Naked Object 被越来越多人认识和应用成熟,Jdon框架也将转向支持另外一个纯OO流派Naked Object, 就象它同时支持POJO派和EJB派一样。
在Jdon框架以后版本中,会很方便支持Naked Object,只要将上面配置文件指向Service去除,CRUD方法由Model自己实现,如下:
<model key="username" class="com.jdon.framework.samples.jpetstore.domain.Account">
<actionForm name="accountForm"/> //指定边界类
<handler>
<!-- <service ref="accountService"> //指定某个业务接口 无需业务层,去除-->
<getMethod name="getAccount"/>
<createMethod name="insertAccount"/> //业务接口的新增方法
<updateMethod name="updateAccount"/> //业务接口的修改方法
<deleteMethod name="deleteAccount"/>
<!-- </service> -->
</handler>
</model>
参考文章:
Ruby on Rails and J2EE technical comparison