`

RichDomainObject的架构设计中,是否可以抛弃DAO?

阅读更多
2、3年过去了,没想到最近Javaeye又有了对Domain设计的热贴,安耐不住,说说自己的想法。

2年前有过尝试RichDomainObject的设计,当时使用的hibernate2+SessionBean。

发现DomainObject必须要依赖Dao(一些业务逻辑执行前,需要对之前产生的DomainObject进行查询或汇总,根据结果判定执行逻辑);
同时为了查询的灵活,Service必须同时依赖Dao和DomainObject

这样整个Server,实际上包括了4种东西:
Service、
ServiceDAO(ReadOnly)、
DomainObject、
DomainDAO(Read/Write)。

另外在Service层和各种Client端(Web/Swing/JavaApplication等)之间使用DTO传递数据。
注意DTO并不是与DomainObject一一对应的的PO无逻辑简化版本,相反DTO是与界面相关的,同一个DomainObject可能根据客户端(界面)的不同,有多个DTO与之对应。(演化到后来DTO变为了由集合、数组、String、Date、Integer等java基础类组合的一个数据结构,系统本身并不存在具体的DTO类,因为数据到界面后只为显示,并没有任何逻辑,无须用对象实现)。

这样的架构下,感觉DAO的处理上实在是繁琐的很,时时有绕过它直接使用hibernate的冲动!

技术在不断进化,JPA的出世,让我看到了一丝希望。

反思一下DAO出现的原始用意:
1)隔离数据库(JDBC)操作。[分层、弱化程序对数据库的直接依赖]
2)简化数据库间移植。[隔离具体数据库接口(SQL)细节,解除厂家邦定]

目前的JPA似乎完全满足了上面两种需求。

而且(JPA)是JAVA持久化API,不是JAVA数据库连接API(JDBC),其从概念上也是不依赖数据库的(完全有可能实现一个使用文件系统/XML进行持久化的JPA)。
同时,JPA本身也是一个隔离层,虽然目前作的不太完美,不过仍然给了你一个可以切换各种不同的JPA实现的机会。

现在看来我们是否可以抛弃DAO了呢?
让代码直接依赖java的标准api--JPA,就像依赖java.util一样?

分享到:
评论
25 楼 pig345 2007-05-17  
xly_971223 写道

springside中OrderManager继承HibernateGenericDao<Order>的方式总感觉有点不对劲,如果OrderManager要用到多个dao不知道怎么实现?


呵呵,我记得有一条OO设计法则就是:不要继承工具类。

24 楼 xly_971223 2007-05-16  
引用
对于业务逻辑复杂的系统,这和我的思路不谋而合;但对于简单的CRUD操作缺显得比较繁琐,像SpringSide中那种统一封装Hibernate 可能更简单。
因此一个关键问题是项目和系统的复杂性。企业级软件往往70%以上的简单CRUD界面操作,加上30%的复杂业务逻辑。如果可能,一种策略是根据子系统或者模块的不同选择不同的设计策略。当然这有会引起复杂性,最后就根据自己项目的情况、人员水平进行权衡了。

springside中OrderManager继承HibernateGenericDao<Order>的方式总感觉有点不对劲,如果OrderManager要用到多个dao不知道怎么实现?
23 楼 pig345 2007-05-16  
myace 写道

企业级软件往往70%以上的简单CRUD界面操作,加上30%的复杂业务逻辑。如果可能,一种策略是根据子系统或者模块的不同选择不同的设计。当然这有会引起复杂性,最后就根据自己项目的情况、人员水平进行权衡了。


比较同意这个策略,实际应用中应该不会引起复杂性,相反可能会使事情变得更简单。

不过我的经验上看,似乎没有什么对数据库的增、改、删操作不涉及到 业务逻辑/领域逻辑 的判定和计算的。
因此他们几乎都可以放到相应的DomainObject中去。

只有查询的操作是只与界面相关而不含有领域逻辑的,因此之前描述的设计中,为了优化性能并顾及查询灵活性,Service/action层是直接使用只读DAO查询DomainObject的。
22 楼 myace 2007-05-16  
pig345 写道
2、3年过去了,没想到最近Javaeye又有了对Domain设计的热贴,安耐不住,说说自己的想法。

2年前有过尝试RichDomainObject的设计,当时使用的hibernate2+SessionBean。

发现DomainObject必须要依赖Dao(一些业务逻辑执行前,需要对之前产生的DomainObject进行查询或汇总,根据结果判定执行逻辑);
同时为了查询的灵活,Service必须同时依赖Dao和DomainObject

这样整个Server,实际上包括了4种东西:
Service、
ServiceDAO(ReadOnly)、
DomainObject、
DomainDAO(Read/Write)。

另外在Service层和各种Client端(Web/Swing/JavaApplication等)之间使用DTO传递数据。
注意DTO并不是与DomainObject一一对应的的PO无逻辑简化版本,相反DTO是与界面相关的,同一个DomainObject可能根据客户端(界面)的不同,有多个DTO与之对应。(演化到后来DTO变为了由集合、数组、String、Date、Integer等java基础类组合的一个数据结构,系统本身并不存在具体的DTO类,因为数据到界面后只为显示,并没有任何逻辑,无须用对象实现)。

这样的架构下,感觉DAO的处理上实在是繁琐的很,时时有绕过它直接使用hibernate的冲动!

技术在不断进化,JPA的出世,让我看到了一丝希望。

反思一下DAO出现的原始用意:
1)隔离数据库(JDBC)操作。[分层、弱化程序对数据库的直接依赖]
2)简化数据库间移植。[隔离具体数据库接口(SQL)细节,解除厂家邦定]

目前的JPA似乎完全满足了上面两种需求。

而且(JPA)是JAVA持久化API,不是JAVA数据库连接API(JDBC),其从概念上也是不依赖数据库的(完全有可能实现一个使用文件系统/XML进行持久化的JPA)。
同时,JPA本身也是一个隔离层,虽然目前作的不太完美,不过仍然给了你一个可以切换各种不同的JPA实现的机会。

现在看来我们是否可以抛弃DAO了呢?
让代码直接依赖java的标准api--JPA,就像依赖java.util一样?



对于业务逻辑复杂的系统,这和我的思路不谋而合;但对于简单的CRUD操作缺显得比较繁琐,像SpringSide中那种统一封装Hibernate 可能更简单。
因此一个关键问题是项目和系统的复杂性。企业级软件往往70%以上的简单CRUD界面操作,加上30%的复杂业务逻辑。如果可能,一种策略是根据子系统或者模块的不同选择不同的设计策略。当然这有会引起复杂性,最后就根据自己项目的情况、人员水平进行权衡了。
21 楼 pig345 2007-05-15  
xly_971223 写道

如果说Dao层可以抛弃 那末service层中的很多对单个Domain object的操作也可以加到DomainObject中

如果是领域相关的逻辑(而不是某个Client/界面独有的)本来就应该放到DomainObject中阿。
20 楼 pig345 2007-05-15  
partech 写道

关于JPA俺不太了解,但是不使用接口,只使用JPA是否能简明的表达如下的概念呢?


花时间看下,你的功力估计不用半天就可了解个大概。
因为与之前的hibernate原理上都很相似的。
而且目前也都是用hibernate作JPA provider
19 楼 pig345 2007-05-15  
partech 写道

多个DAO interface和implements,如果里面的方法和实现确实不同,那么是没办法减少这部分代码的,对么?


如果没理解错,你的“实现不同”多数是指针对不同的数据库产品的SQL不同吧,好像是jpa(或者之前的hibernate/toplink...)已经解决了这个问题。

其实仔细想想一般的BO+PO+DAO的设计里面,逻辑是分散在3种对象中的,BO 里有流程逻辑、PO 里是领域结构、一些复杂的情况中,DAO里面的SQL也体现了一部分业务计算逻辑。

将BO简化为Service(Action层),用来控制事务边界;业务逻辑和相关的PO结合形成DomainObject,并且DomainObject直接使用JPA(以及相关的JPQL查询语言),会保证所有领域逻辑都体现在对应的DomainObject中。

这样可能会带来DomainObject的复杂化,但是业务逻辑集中。

选择 复杂但少量(相对)精简的代码,还是 简单但大量(相对)臃肿的代码,这是一个问题阿!
18 楼 xly_971223 2007-05-15  
shaucle 写道
xly_971223 写道

如果说Dao层可以抛弃 那末service层中的很多对单个Domain object的操作也可以加到DomainObject中


俺还是认为Domain object瘦一点的好.
瘦一点的享受的服务通常更多,也更灵活.

如果要抛弃的话就来的彻底一些
当然我个人也不喜欢domain object带一些dao操作 那样的话客户端岂不是可以通过domain object调用dao方法了 就有点乱套了
17 楼 shaucle 2007-05-15  
xly_971223 写道

如果说Dao层可以抛弃 那末service层中的很多对单个Domain object的操作也可以加到DomainObject中


俺还是认为Domain object瘦一点的好.
瘦一点的享受的服务通常更多,也更灵活.
16 楼 xly_971223 2007-05-14  

如果说Dao层可以抛弃 那末service层中的很多对单个Domain object的操作也可以加到DomainObject中
15 楼 shaucle 2007-05-14  
dovecat 写道
等到JPA用的差不多了,大家又会觉得JPA也不是个好东东的说.


同意这个的说,不然事物怎么发展。
老马的理论还是很强的!
14 楼 dovecat 2007-05-14  
等到JPA用的差不多了,大家又会觉得JPA也不是个好东东的说.
13 楼 partech 2007-05-14  
pig345 写道
多了 Dao Interface / Dao Implements + 你自己写的Factory或Spring的配置。这许多的类不是很麻烦么?

主要是考虑当前的开发环境的进化, JPA 既然成为了标准API,我们能否信任他,就像信任java.util一样?

而且个人觉得现在大家似乎过分强调解偶,解偶也是有限度的,你不可能不依赖 java.lang java.util 来写程序吧。

多个DAO interface和implements,如果里面的方法和实现确实不同,那么是没办法减少这部分代码的,对么?

关于配置问题,可以使用一个Aspect搞定,因为可以查找到Dao interface和implements的关系。

关于JPA俺不太了解,但是不使用接口,只使用JPA是否能简明的表达如下的概念呢?

interface IProductFinder{
   //查找客户在用产品
    List findByCustomerCode(String code);
}
12 楼 shaucle 2007-05-14  
用了jpa就知道dao是多余的

其实不用也感觉得到这个东东就有点无中生有...

不过个人感觉jpa还可以简化(但未必是好事)
11 楼 pig345 2007-05-14  
partech 写道
pig345 写道
这样的架构下,感觉DAO的处理上实在是繁琐的很,时时有绕过它直接使用hibernate的冲动!

敢问,如何繁琐的很呀?

多了 Dao Interface / Dao Implements + 你自己写的Factory或Spring的配置。这许多的类不是很麻烦么?

主要是考虑当前的开发环境的进化, JPA 既然成为了标准API,我们能否信任他,就像信任java.util一样?

而且个人觉得现在大家似乎过分强调解偶,解偶也是有限度的,你不可能不依赖 java.lang java.util 来写程序吧。
10 楼 pig345 2007-05-14  
还是需要澄清一下,虽然与http://www.iteye.com/topic/56949讨论的都是Domain和DAO的关系问题,但是具体的实现选择根本不同。
大家在那里面讨论最多的似乎就是我所反对的(domain extends DAO 或 BO extends PO),而这里提出的是Domain直接使用JPA从而消除DAOinterface/DAOImpl !
9 楼 partech 2007-05-14  
pig345 写道
这样的架构下,感觉DAO的处理上实在是繁琐的很,时时有绕过它直接使用hibernate的冲动!

敢问,如何繁琐的很呀?
8 楼 shaucle 2007-05-14  
giscat 写道
pig345 写道
giscat 写道
如果你是老大,怎么玩都可以
当然包括自虐

技术讨论帖子,为什么要有嘲讽和人身攻击?请明确解释你的看法。


非常诚恳地声明一下:
并没有嘲讽和人身攻击嘛
切勿多愁善感,否则后果自负


本来就说得对嘛! 呵呵!
7 楼 pig345 2007-05-14  
lighter 写道
相关的讨论,看如下:
http://www.iteye.com/topic/56949
这样的问题,即使争论不休也得不出什么结果的,不过标题惹人眼球


刚发完本帖,就看到了,还没看完。。。

无须争论,项目里实践下,毕竟省代码行数、省工作量、省测试量,才是硬道理。
6 楼 shaucle 2007-05-14  
pig345 写道
顺便说一下,本人极其不赞成使用BO(业务逻辑) extends PO(持久化)= DomainObject 的方式,虽然从代码上看,好像还算干净漂亮。
但是要知道,DomainObject是领域对象,他的extends应该体现业务逻辑对象之间的天然继承关系,而不要将这(在JAVA这种单继承静态类型语言里面是极其)宝贵的资源浪费到具体实现手段上!




俺也这么认为,而且好像这种趋势越来越明显..
失血又怎么样,失血正好表明职责分明.

相关推荐

    DAO设计模式DAO设计模式

    DAO设计模式DAO设计模式DAO设计模式DAO设计模式DAO设计模式DAO设计模式DAO设计模式DAO设计模式DAO设计模式DAO设计模式

    基于JSP+Servlet+JavaBean+JDBC+DAO的Web图书管理架构设计该系统

    基于JSP+Servlet+JavaBean+JDBC+DAO的Web架构设计该系统,进一步了解并掌握如何对数据库进行操作,以及如何分析、设计一个应用系统。 需求要求: 该系统的基本需求是,系统要实现如下的基本管理功能: (1)用户分为...

    dao_ji_shi.rar_dao?ji?shi

    实现利用Timer倒计时,调整Interval可调整分钟或小时

    DAO设计模式 DAO 设计模式 JAVA设计模式

    DAO设计模式 DAO 设计模式 JAVA设计模

    J2EE之DAO设计模式

    当底层数据存储实现不需要发生改变时,该策略可以使用工厂方法设计模式实现,来产生应用中所需的DAO. 当底层数据储存实现不得不发生变化的时候, 我们可以用抽象工厂模式来实现这个策略. 在当前情况,可以提供一个抽象...

    Dao设计模式

    java,dao设计模式,主要介绍Dao三层架构的设计模式,让我们更加深入理解Java 框架。

    泛型dao 泛型dao 泛型dao

    1)dao类的繁多,很多设计都是一个entity对应一个dao (不同的只有类名和方法名) 2)dao接口需要维护的method庞大。 3)业务逻辑改变时,dao需要同时修改两个类文件(接口和实现类) 在本文中,我将为您展示如何...

    李兴华DAO设计模式

    李兴华DAO设计模式

    j2ee 架构设计 (SSH典型结构解析)

    j2ee 架构设计 第一部份:介绍实例架构 结合实例讲解Web项目总体结构 分析多层结构优点 具体讲解每个层次的实现技巧 第二部分:介绍组织层次关联利器(Spring) 快速入门 Factory模式 IOC模式 AOP模式 演练Spring的...

    基于DAO设计模式的新闻发布系统

    基于DAO设计模式的新闻发布系统基于DAO设计模式的新闻发布系统基于DAO设计模式的新闻发布系统基于DAO设计模式的新闻发布系统基于DAO设计模式的新闻发布系统

    DAO设计模式及源码

    DAO设计模式是属于J2EE数据层的操作,使用DAO设计模式可以简化大量代码,增强程序的可移植性。

    Dao设计模式教程

    本教程主要介绍了Dao设计模式,并且还有一些实例

    基于J2EE架构的生产管理系统设计

    详细设计实现过程中, 采用Netbeans、Eclipse、Oracle、Tomcat 等作为开发工具,在持久层使用轻量级ORM 开源框架Hibernate 技术,结合DAO 设计模式。用Spring 的IOC 和AOP 技术对持 久层和业务逻辑层对象进行管理,...

    DAO设计模式Demo

    DAO(Data Access Object)是一个数据访问接口,数据访问:顾名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。 本文按照DAO设计模式的思想,设计并实现了该模式架构。

    java设计三层架构

    java设计 三层架构设计模型 javaWeb开发中常用模型

    MVC三层架构+DAO工厂模式进行JAVA WEB开发

    MVC三层架构+DAO工厂模式进行JAVA WEB开发

    DAO设计模式(工厂+代理)

    用简单易懂的例子说明DAO设计模式(附带sql脚本,mysql数据库)

    DAO设计模式

    DAO设计模式

    DAO设计模式精讲(java web开发)

    DAO设计模式DAO设计模式,网上多份精华讲解汇总!

    Java Dao设计模式操作数据库

    自己写的java Dao设计模式操作数据库,很方便。

Global site tag (gtag.js) - Google Analytics