锁定老帖子 主题:一个DAO的设计的小问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2004-07-13
jxb8901 写道 我想首先我们要达成一个共识,就是相信OO能给我们的"痛苦"带来解脱,构建一个真正OO的系统是我们的追求,如果连这一点都不能认同那其它的就不要谈了. 我这里说的是真正的OO的系统,而不是指OO的编程语言,实际上这两者没有关系.而transaction script的提出,我想主要就是指用OO的语言做出来的过程式的系统,这类系统我们见的太多了,而真正OO的系统却太少了,我的理解domain object就是指的真正OO的系统. 另外我讲OO是我们的追求,是目标,如你所说我们一下也不可能做完善理想的系统,但心中应该有这样一个远景,我们要使系统尽量OO,因为我们要让自己尽量轻松.
我想关于OO的共识我们是有的 我觉得domain object是不是就是真正的OO系统还要再想想 关于什么是真正的OO系统,能说说你的想法吗? 对于我来说 现在还是少说些主义,多做些工作先 jxb8901 写道 flyingbug 写道 这个程序有两层,底层就是我前面说的DAO(包含部分业务逻辑的) 然后就是Swing的GUI层,所有的业务逻辑全部写在GUI层 有的是几个功能界面写在一个类里,一个方法200行算少的 (第一次看到它的时候我想起VB了) 我就是想把业务逻辑层剥离出来(为了将来在web上的应用) 所以才牵扯出前面的问题 这就是我们见得太多的用OO语言做的过程式的系统,当然不是讲这种系统一无是处,如果它不让人心烦,尽可以用这种方法做系统,但一旦让我们头大了,我想我们也应该修理它了.办法当然是改为三层!前面和后面的就不说了,中间的当然是业务逻辑,具体这一层怎么做,我想这一层才是我们做应用的程序员发挥的地方,各人有各人的做法,我认为要注意的是:1.表示层尽量单薄,只展示数据,现在大多数的WEB框架已经强迫我们这样做了;2层间的接口层(facade层)也要注意不要放置业务逻辑,facade只做转发,要注意service也是一种facade;3数据层只负责数据提取与持久化,不要涉及任何业务逻辑,这一点比较难做到,因为我们一不小心就把业务逻辑放在了DAO或者PO中了. 但如果是先分析业务得出业务对象(domain object), 最后考虑持久化,我想这一点也不难了.千万不要先分析数据库表结构,再考虑是一个表一个对象呢,还是一个表多个对象呢还是多个表一个对象,这样做的话,我只能说两个字"完了". 另外,我还想提醒一下,善用"隐喻",对于得出OO的系统有很大的帮助. 另外这一贴放在这个版面好象不太合适? 最后的这段话说的很实在 也是我接手这个项目的想法 第一、二点不用说 第三点我觉得不是我一个人的问题, 先分析domain object也一样可能产生蔓延出边界的业务对象 在这个论坛上也很多次讨论过这个问题 我没看到有人提出有什么优美的解决方案 大部分的讨论最后都是“随需应变” 如果从分析业务的domain object出发 那就是重新分析了,这个时间上是不允许的 如果是使用entity bean做还有可能(退化的domain object) 我现在希望在现有资源下获得一个尽量灵活的解决方案 jxb8901 写道 另外这一贴放在这个版面好象不太合适?
呵呵,不好意思,第一次提问也没细想发在哪 |
|
返回顶楼 | |
发表时间:2004-07-13
首先需要说明的是,DAO是一种设计模式(相信大家都是知道的,之所以还要指出来,
是想我们的讨论不会偏离方向)。这种设计模式的最主要目的是抽象对数据源的访问。 因此,严格地说,就不能把DAO说成是“层”。 其次,再来说说“层”。在所有的设计模式之上,还有一种更高级的模式,这种模式主要 用来定义系统的组织结构及其关系,称为构架模式,其中,最重要的一种构架模式就是 层模式,这个我们大家都知道了,比如你的系统会分为表示层,业务逻辑层,数据访问 层,等等。特别地,对于数据访问层,DAO不是唯一选择,比如,可以选择Entity Bean作为数据访问层。 在上述背景下,对于你的问题就可以更清晰的表达为:“在使用DAO模式的数据访问层中, 如何界定类的职责?”。让我们来仔细的分析一下这个问题。 由上面的论述,我们就可以断定,类的职责划分,应该是由DAO模式和构架设计来决定 的,而无论是DAO模式,还是构架设计,通常要求数据访问层具备如下职责: --查询数据对象 --创建,保存和删除数据库记录。 --可选的,还可提供事务处理支持。 所以,只要是数据库相关操作,原则上就都可以放到这里面,无所谓可以不可以,只有 相对的好或不好。因此,这很大程度上就取决于设计人员(通常是构架设计师)的经验 与项目的具体情况。 问题好像并没有解决啊,这样的回答是不能让人满意的。我想,这可能是一个实践性 很强的问题,实践不同,得到的答案就不可能相同。那么,让我们来看看下面的实践 (希望能找到最佳实践): 1.数据访问层以DAO模式实现 1)实现方式。先定义接口,然后针对不同的数据库(mysql/ms sql server或 oracle等)和不同的实现方式(jdbc或hibernate等)给出具体的实现。 2)职责。每个类对一个数据库表进行维护,即增/删/改只针对一个表;查询则可以 连接多个表。考虑到重用性大小,可以有限度的增加业务逻辑相关的代码。 3)与其他层传递的对象。使用领域模型对象(domain object),如果是 hibernate实现,领域模型对象即成为PO(persistence object)。领域模型对 象不能包含业务逻辑方法,当然作为业务逻辑的一部分--验证逻辑,原则上也不应该 包含在内的。可选的,这个领域模型对象在被传递到更上一层的时候,可以选择继续保 持数据库状态,也可以不保存,可以被传递到更多层,也可以只传递到前一层,这取 决于你的构架设计,与本话题无关。 2.数据访问层以EntityBean实现 1)实现方式。首选CMP。 2)职责。通过配置文件与单一表进行映射,对该表进行增删改;查询使用EJBQL, 可以从多个表查询数据(join)。考虑到重用性大小,可以有限度的增加业务逻辑相 关的代码。 3)与其他层传递的对象。使用领域模型对象(domain object),此时,也称为 VO(Value Object, 或者transfer object),典型地,这个vo被传递到上一 层的业务逻辑层(通常是一个SLSB),并有可能继续传递到WEB控制器,当然,这也 不在本话题讨论范围之内。 大家一起讨论讨论 |
|
返回顶楼 | |
发表时间:2004-07-14
首先问一下,什么是业务逻辑?
平均工资 = 所有人的工资总和 / 人数,嗯,这个看起来是个业务逻辑。 但是如果换成一个字段的数据的平均值,呃,一下子就变成不是业务逻辑了!? 剥离了业务语义,操作就被抽象出来了,不再属于业务逻辑了。 所以,我认为DAO可以提供剥离了业务语义的抽象操作。 其次, 引用 在DAO中用left join从其他的数据表中取得 ,这并不意味着把业务逻辑放到了DAO中。
业务逻辑里没有数据如何存储的要求。 人事部门的出勤统计,不会强制要求你把员工姓名跟刷卡数据放到你一个表里,但是会要求它们出现在一个PO里。 你可以把系统的数据看作弱水三千,每一个业务逻辑都只是饮取一瓢。DAO就是瓢。而如何使用这个瓢,那是业务逻辑自己的问题。 至于弱水三千是先放在很多缸子里,用的时候再倒到池子里,还是一直放在池子里,这跟业务逻辑一点关系都没有。 |
|
返回顶楼 | |
发表时间:2004-07-14
mis98zb 写道 首先问一下,什么是业务逻辑?
平均工资 = 所有人的工资总和 / 人数,嗯,这个看起来是个业务逻辑。 但是如果换成一个字段的数据的平均值,呃,一下子就变成不是业务逻辑了!? 剥离了业务语义,操作就被抽象出来了,不再属于业务逻辑了。 所以,我认为DAO可以提供剥离了业务语义的抽象操作。 你说的抽离了业务语义的抽象操作很有道理 可是虽然DAO不再工作在业务逻辑的语义环境下 它的设计依然受到业务逻辑的驱动 或者说它虽然抽象了业务逻辑的语义 但是它并没有抽象出所涉及数据的关系 mis98zb 写道 其次, 引用 在DAO中用left join从其他的数据表中取得 ,这并不意味着把业务逻辑放到了DAO中。
业务逻辑里没有数据如何存储的要求。 人事部门的出勤统计,不会强制要求你把员工姓名跟刷卡数据放到你一个表里,但是会要求它们出现在一个PO里。 你可以把系统的数据看作弱水三千,每一个业务逻辑都只是饮取一瓢。DAO就是瓢。而如何使用这个瓢,那是业务逻辑自己的问题。 至于弱水三千是先放在很多缸子里,用的时候再倒到池子里,还是一直放在池子里,这跟业务逻辑一点关系都没有。 那就是说在设计DAO的时候 我可以一次性的把业务的数据和关系全部放到一个PO里面 这样相关业务的各种应用就可是使用这个统一的PO 虽然某些数据在有些应用里是用不到的 也就是说一个业务逻辑需要一个瓢,而不是每个应用都需要一个瓢 是不是这个意思? |
|
返回顶楼 | |
发表时间:2004-07-14
zhaohui1004 写道 所以,只要是数据库相关操作,原则上就都可以放到这里面,无所谓可以不可以,只有相对的好或不好。因此,这很大程度上就取决于设计人员(通常是构架设计师)的经验与项目的具体情况。 问题好像并没有解决啊,这样的回答是不能让人满意的。我想,这可能是一个实践性很强的问题,实践不同,得到的答案就不可能相同。那么,让我们来看看下面的实践(希望能找到最佳实践): 1.数据访问层以DAO模式实现 1)实现方式。先定义接口,然后针对不同的数据库(mysql/ms sql server或 oracle等)和不同的实现方式(jdbc或hibernate等)给出具体的实现。 2)职责。每个类对一个数据库表进行维护,即增/删/改只针对一个表;查询则可以连接多个表。。 3)与其他层传递的对象。使用领域模型对象(domain object),如果是 hibernate实现,领域模型对象即成为PO(persistence object)。领域模型对象不能包含业务逻辑方法,当然作为业务逻辑的一部分--验证逻辑,原则上也不应该包含在内的。可选的,这个领域模型对象在被传递到更上一层的时候,可以选择继续保持数据库状态,也可以不保存,可以被传递到更多层,也可以只传递到前一层,这取决于你的构架设计,与本话题无关。 hi,谢谢回复^_^ 你这段把DAO的职责说的很清楚 但能详细说说 zhaohui1004 写道 考虑到重用性大小,可以有限度的增加业务逻辑相关的代码
这句话中这个重用,是指给不同的业务重用还是给一个业务的不同功能重用? 怎样增加相关的业务逻辑代码呢? |
|
返回顶楼 | |