这个例子很老啦,在之前的Domain Model的争论中被广泛引用(参见:http://www.iteye.com/topic/11712)。我再来炒炒冷饭。
这个Domain可以简化为这样:
public class Item {
private Set<Bid> bids = new HashSet<Bid>();
}
public class Bid {
private User bidder;
private int amount;
}
现在我们要添加一个行为叫placeBid。于是我们可以写出如下的贫血代码:
Bid currentMaxBid = itemDAO.getMaxBid(itemId);
Item item = itemDAO.findById(itemId, true);
if (currentMaxBid != null && bidAmount <= currentMaxBid.getAmount()) {
throw new BizException("Bid too low.");
}
Bid newBid = new Bid(this, bidder, bidAmount);
item.getBids().add(bid);
itemDao.save(item);
这样的代码有什么问题吗?我觉得在没有更多的需求,系统规模不大的情况下,无法拿出有力的证据证明这样做的缺陷。那么我们再来看看如何用经典的Hibernate做法来做领域模型(参见robbin的第二种模型):
public class Item {
public Bid placeBid(User bidder, int bidAmount, Bid currentMaxBid) {
if (currentMaxBid != null && bidAmount <= currentMaxBid.getAmount()) {
throw new BizException("Bid too low.");
}
Bid newBid = new Bid(this, bidder, bidAmount);
bids.add(newBid);
return newBid;
}
}
在那篇老帖子(我知道,n年前了)中,七彩狼提出了一个问题,就是:
引用
第三类DomainLogic,也就是需要依赖到复杂查询的Logic
那需要这样的逻辑的是什么?远在天边,近在眼前。currentMaxBid哪来的?不还是从DAO中取出来的嘛。我Item包含了自己的bids,它居然没有办法知道maxBid是什么,还需要从外边用参数传进来。这是不合理的,但是却是不得已的。Hibernate的经典解决方案制约我们必须把这样的查询逻辑放在Domain的使用者那一边中调用DAO来完成。如果改用(http://www.iteye.com/topic/191261)我说的RichSet,就可以轻松解决:
public class Item {
private RichSet<Bid> bids = new DefaultRichSet<Bid>();
public Bid placeBid(User bidder, int bidAmount) {
Bid currentMaxBid = bids.max("amount");
if (currentMaxBid != null && bidAmount <= currentMaxBid.getAmount()) {
throw new BizException("Bid too low.");
}
Bid newBid = new Bid(this, bidder, bidAmount);
bids.add(newBid);
return newBid;
}
}
max在缺省情况下的实现是遍历列表。在Hibernate增强之后就变成了SQL查询。类似于bids.add在缺省情况是列表操作,Hibernate存储的时候变成了SQL的INSERT。
我的观点是,所谓的大批量操作不属于Domain Logic是由于Hibernate造成的限制。实际情况中,Domain中应该有一个叫Repository的对象。它封装了一个List。
public class ItemRepository {
private RichList<Item> items
public ItemRepository(RichList<Item> items) {
this.items = items;
}
}
作为领域对象的ItemRepository,它是不关心items是从哪里来的。它就认为这个items是domain中的所有的item。于是,addItem的item没名字不重复的校验就可以自然的放在ItemRepository上。
public class ItemRepository {
public void addItem(String name) {
if (items.find("name").eq(name).size() > 0) {
throw new BizException("name duplicated");
}
Item item = new Item(name);
items.add(item);
return item;
}
}
在Domain中,所有的Item列表,都应该经过ItemRepository包装。从而保证Item的名字唯一性。
分享到:
相关推荐
该类实现了 `PlaceBid` 接口,该接口定义了一个 `addBid` 方法,用于添加一个新的竞标。通过这种方式,EJB3 允许开发者以一种简洁、易于理解的方式实现复杂的业务逻辑。 #### 热门提示和其他技巧 除了上述内容外,...
public class PlaceBidBean implements PlaceBid { public PlaceBidBean(){} public Bid addBid(Bid bid){ System.out.println("Adding bid, bidderID=" + bid.getBidderID() + ",itemID=" + bid.getItemID()...
9. **placebid.asp** - 用户出价的页面,包含出价验证(如是否超过当前最高价、用户是否有足够的资金等)和记录出价的逻辑。 10. **postitem.asp** - 提交拍卖物品的页面,用户确认发布后,ASP代码会处理上传的商品...
拍卖应用 以太坊智能合约,以模拟标准的英语拍卖。 智能合约功能: addListing(itemName:字符... placeBid(itemId:number)应付帐款 withdraw(itemId:数字) getTotalBid(itemId:数字,bidderAddress:地址)
基于java网上球鞋竞拍系统设计与实现.docx
基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip 个人大四的毕业设计、课程设计、作业、经导师指导并认可通过的高分设计项目,评审平均分达96.5分。主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 [资源说明] 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设或者课设、作业,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96.5分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),供学习参考。
基于java的足球赛会管理系统设计与实现.docx
基于java的婚纱摄影网的设计与实现.docx
项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
基于java的农产品仓库管理系统系统设计与实现.docx
【作品名称】:基于Java swing +mysql(Oracle)实现的飞机订票系统项目(含毕业论文+答辩 ppt+双数据库版本源码) 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】: 系统功能需求 本系统用于远程机票预订,包括远程航班信息查询、机票预订与确认等;主要分为四大功能:查询、订票、退票和管理。 管理员登录、注销 到系统并进行插入、删除、更新以及查看机票后台数据库操作 插入:机票的插入可以按照航班号、班期、公司、座位号、起飞地以及抵达地等等插入数据库。 删除:机票可以按照航班号、起止城市、星期进行删除 3.1.1客户端系统功能 1.普通用户: 查询:根据航班号、航空公司以及目的地查询出票类信息 订票: 根据出发日期和第一航班号预订机票,机票类型分为单 【资源声明】:本资源作为“参考资料”而不是“定制需求”,代码只能作为参考,不能完全复制照搬。不一定能够满足所有人的需求,需要有一定的基础能够看懂代码,能够自行调试代码并解决报错,能够自行添加功能修改代码。
2018信基广场“红动佛山”春节新媒体营销方案.pptx
均包含代码,文章,部分项目包含ppt
基于java的蜀都天香酒楼的网站设计与实现.docx
1、开发环境:SSM框架;内含Mysql数据库;VUE技术;内含说明文档 2、项目代码都经过严格调试,代码没有任何bug! 3、该资源包括项目的全部源码,下载可以直接使用! 4、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 5、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。
基于java的英语单词学习网站设计与实现.docx
基于java企业销售人员培训系统设计与实现.docx
2019优益C x 易烊千玺微博营销案结案报告.pptx
基于java的单位人事管理系统设计与实现.docx
该网站采用SSM框架和Eclipse编辑器、MySQL数据库设计并实现的。网站功能包含系统用户管理、图书管理、用户管理、借书管理、续借管理、违章缴款管理等模块。 首页是网站的入口,主要包含了:新闻信息、图书信息等导航功能。 用户有独立的注册界面,用户填写好注册信息后,会有个一审核的过程,经过管理员审核注册成功,并将注册的信息加入用户表中。 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7+ 后端技术:ssm 前端技术:Vue 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog