该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-03-25
那你这种方式就是同时给Web层程序员暴露ItemManager和ItemDao两个服务接口,这样的话,有两个重大缺陷:
1、直接暴露ItemDao,却没有事务控制 Web程序员对于简单的CRUD操作,他只能去直接调用ItemDao了,但是你没有给ItemDao提供事务声明。 当然你可以说我也给ItemDao提供容器事务,但是如果那样的话,你的ItemDao和ItemManager就没有本质的区别了,还不如合并起来简洁。 2、同时给一个domain object提供两个可供操作的接口,让Web程序员非常困扰,无所适从。不符合单一服务入口点的原则。 |
|
返回顶楼 | |
发表时间:2005-03-25
引用 domain logic也分为两类: 第一类:需要持久层框架隐式的实现透明持久化的domain logic this.getBids();.add(newBid);; 第二类:完全不依赖持久化的domain logic class Topic { boolean isAllowReply(); { Calendar dueDate = Calendar.getInstance();; dueDate.setTime(lastUpdatedTime);; dueDate.add(Calendar.DATE, forum.timeToLive);; Date now = new Date();; return now.after(dueDate.getTime(););; } } 我觉得这个分类不完整。 上面的第一类,实际上,只是 domain logic 依赖 Create Update Delete 这些持久化方法,并没有包括 Read 持久化方法。 应该还有第三类,即 Domain Logic 依赖 查询或复杂查询 。 对上面 Item 的例子,我们添加这样的一个需求,即 Item.Name 不能重复。因此,我们会得到下面的代码: public class ItemManager implements ItemManager extends HibernateDaoSupport { public Item loadItemById(Long id); { return (Item); getHibernateTemplate();.load(Item.class, id);; } public Collection findAll(); { return (List); getHibernateTemplate();.find("from Item");; } public void updateItem(Item item); { // 从数据库中读取等于 Item.Name 且 不包含自身 的所有 theSameNameItems // 如果存在相同名字的 Item 则 throw BizException("存在相同名称的Item");; getHibernateTemplate();.update(item);; } public Bid placeBid(Item item, User bidder, MonetaryAmount bidAmount, Bid currentMaxBid, Bid currentMinBid); throws BusinessException { item.placeBid(bidder, bidAmount, currentMaxBid, currentMinBid);; updateItem(item);; // 确保持久化item } } 对于这样的逻辑,我们究竟应该放在何处呢? |
|
返回顶楼 | |
发表时间:2005-03-25
对于上面我所提到的第三类DomainLogic,也就是需要依赖到复杂查询的Logic。
我们究竟是应该将其当做 业务逻辑 放在 Manager 之内呢? 还是应该将其当做 Domain Logic 放在 Domain Model 之内呢? 我个人认为,就上面的例子来说 Item.Name 不能有重复,应该是 Domain Logic 的一部分。也就是说,这种 logic 应该是放入 Domain Model 之内,才更为合理。 但如果将查询操作,置入 Domain Model 之内,似乎又与我们的初衷不符合,Domain Model 不应该依赖于 DAO 。 |
|
返回顶楼 | |
发表时间:2005-03-25
2点疑问:
1 刚开始的讨论是基于领域模型为前提,到现在已经是技术便利为前提了。还是觉得庄表伟所说更有意义。应该基于“含义”。而不是相反却依赖技术。技术应该是为设计建模服务的吧. 2 孰愚昧,这样的DAO和业务逻辑混合的变种,一种持久化的实现已经直接渗透到了业务逻辑层。这样的看法正确吗? 望ROBBIN能对如何权衡这些优缺点进行说明一下。我觉得第一种变种优点更大一些。可以利用工具来解决它的一些缺点。 |
|
返回顶楼 | |
发表时间:2005-03-25
zhu1230 写道 2点疑问:
1 刚开始的讨论是基于领域模型为前提,到现在已经是技术便利为前提了。还是觉得庄表伟所说更有意义。应该基于“含义”。而不是相反却依赖技术。技术应该是为设计建模服务的吧. 2 孰愚昧,这样的DAO和业务逻辑混合的变种,一种持久化的实现已经直接渗透到了业务逻辑层。这样的看法正确吗? 望ROBBIN能对如何权衡这些优缺点进行说明一下。我觉得第一种变种优点更大一些。可以利用工具来解决它的一些缺点。 其实我在前面已经强调过一次,在这里再强调一次。 为什么O/R Mapping流行之前,我们无法使用Rich domain object的模型?就是因为技术限制。我在02年的时候已经采用Rich domain object做了一个小项目,但是做到后来不得不全部改成贫血的domain object?你说你设计软件架构的时候能够完全抛开技术限制,天马行空的随便搞吗?不可能的。 软件系统的设计本身就是一个以业务逻辑为核心建模,同时又必须根据技术水平进行折衷的过程。如果你在开始设计的时候完全不考虑技术实现能力,那么你必然会导致和我一样的经历,做到最后全部推翻重新来过。 |
|
返回顶楼 | |
发表时间:2005-03-25
七彩狼 写道 对于上面我所提到的第三类DomainLogic,也就是需要依赖到复杂查询的Logic。
我们究竟是应该将其当做 业务逻辑 放在 Manager 之内呢? 还是应该将其当做 Domain Logic 放在 Domain Model 之内呢? 我个人认为,就上面的例子来说 Item.Name 不能有重复,应该是 Domain Logic 的一部分。也就是说,这种 logic 应该是放入 Domain Model 之内,才更为合理。 但如果将查询操作,置入 Domain Model 之内,似乎又与我们的初衷不符合,Domain Model 不应该依赖于 DAO 。 小板凳中,等待着Robbin和Partech对如上问题的解惑。。。 。。。 |
|
返回顶楼 | |
发表时间:2005-03-25
TO Robbin
我提倡的模型中, 不存在你说的那种业务逻辑对象。 Service层对象是单独的一层,它不属于业务层,它包裹着业务层。 在我的模型中业务层的对象包括 1.业务对象: 1.1.业务控制对象; 1.2.业务实体对象; (上面两类对象如果站在足够的高度其实是一类对象) 2.业务层调用其它服务需要的接口和封装接口的相关对象。持久化接口(例如UnitOfWork接口,DAO的接口,封装接口的Repository对象)只是其中之一。 整体结构如下: ServiceInferface<-----Service----->DomainModel<----->DAOInterface<-----DAOImplement----->DataBase, DomainModel<------DAOImplement。 |
|
返回顶楼 | |
发表时间:2005-03-25
七彩狼 写道 对于上面我所提到的第三类DomainLogic,也就是需要依赖到复杂查询的Logic。
我们究竟是应该将其当做 业务逻辑 放在 Manager 之内呢? 还是应该将其当做 Domain Logic 放在 Domain Model 之内呢? 我个人认为,就上面的例子来说 Item.Name 不能有重复,应该是 Domain Logic 的一部分。也就是说,这种 logic 应该是放入 Domain Model 之内,才更为合理。 但如果将查询操作,置入 Domain Model 之内,似乎又与我们的初衷不符合,Domain Model 不应该依赖于 DAO 。 如果你想偷懒,就让数据库的索引来解决你的问题. 或者可以在控制对象中检查是否重复,考虑到乐观并发,数据库的索引还是需要的。 public class ItemManager { public Bid placeBid(...); { Item item = findByName(name);; if(item != null); throw new businessException("Duplicate item found.");; ... } } |
|
返回顶楼 | |
发表时间:2005-03-25
七彩狼 写道 对于上面我所提到的第三类DomainLogic,也就是需要依赖到复杂查询的Logic。
我们究竟是应该将其当做 业务逻辑 放在 Manager 之内呢? 还是应该将其当做 Domain Logic 放在 Domain Model 之内呢? 我个人认为,就上面的例子来说 Item.Name 不能有重复,应该是 Domain Logic 的一部分。也就是说,这种 logic 应该是放入 Domain Model 之内,才更为合理。 但如果将查询操作,置入 Domain Model 之内,似乎又与我们的初衷不符合,Domain Model 不应该依赖于 DAO 。 也来和各位凑个热闹。 我目前的项目中这种情况很多,建立时Name不能重复,修改时Name不能重复,删除时要看(数据库中)与其关联的其他DomainObject的状态。 "我们究竟是应该将其当做 业务逻辑 放在 Manager 之内呢?还是应该将其当做 Domain Logic 放在 Domain Model 之内呢?" |
|
返回顶楼 | |
发表时间:2005-03-25
引用 如果你想偷懒,就让数据库的索引来解决你的问题.
或者可以在控制对象中检查是否重复,考虑到乐观并发,数据库的索引还是需要的。 这并没有解决我的疑惑,我的问题是,象这类依赖数据库查询的 Logic ,是放在 Manager 内合适,还是放在 Domain Model 内合适。 我觉得应该放入,Domain Model 内更适合,因为这种业务校验,也的确属于 Domain Logic 的范畴。 引用 1.“DomainModel的持久化与封装”;
2.“大数据量操作”; 我在前面提到过,我对模型2还存在一些疑惑,这便是其中的一个。 我将这类问题,称为“大数据量操作”问题,这个名字不是很恰当,希望能有人给出更好的表达方式。 这类问题的特点是,单个 Domain Model 内的 Domain Logic ,实际上是依赖 整个 Domain Model 集合的。 就上面Item的例子来讲,Item是否符合自身的校验规则,是需要依赖所有的 Item 的。即当判断这个 Item 是否合法时,我们需要查找所有的 Item 来进行相关的校验。 这类问题,应该是 Domain Logic 的一部分。放在 Manager 之内,似乎并不适合。 但我们现在有需要尽量是 Domain Logic 最少甚至不依赖与 DAO ,我们该怎么办? |
|
返回顶楼 | |