失血模型,贫血模型,充血模型,胀血模型

上传人:wm****3 文档编号:41784300 上传时间:2018-05-31 格式:DOC 页数:16 大小:60KB
返回 下载 相关 举报
失血模型,贫血模型,充血模型,胀血模型_第1页
第1页 / 共16页
失血模型,贫血模型,充血模型,胀血模型_第2页
第2页 / 共16页
失血模型,贫血模型,充血模型,胀血模型_第3页
第3页 / 共16页
失血模型,贫血模型,充血模型,胀血模型_第4页
第4页 / 共16页
失血模型,贫血模型,充血模型,胀血模型_第5页
第5页 / 共16页
点击查看更多>>
资源描述

《失血模型,贫血模型,充血模型,胀血模型》由会员分享,可在线阅读,更多相关《失血模型,贫血模型,充血模型,胀血模型(16页珍藏版)》请在金锄头文库上搜索。

1、一、失血模型失血模型简单来说,就是 domain object 只有属性的 getter/setter 方法的纯数据类,所有 的业务逻辑完全由 business object 来完成(又称TransactionScript),这种模型下的 domain object 被 Martin Fowler 称之为“贫血的 domain object” 。下面用举一个具体的代码来说明,代码来自 Hibernate 的 caveatemptor,但经过我的改写:一个实体类叫做 Item,指的是一个拍卖项目 一个 DAO 接口类叫做 ItemDao 一个 DAO 接口实现类叫做 ItemDaoHiberna

2、teImpl 一个业务逻辑类叫做 ItemManager(或者叫做 ItemService)java 代码: public class Item implements Serializable private Long id = null;private int version;private String name;private User seller;private String description;private MonetaryAmount initialPrice;private MonetaryAmount reservePrice;private Date startDat

3、e;private Date endDate;private Set categorizedItems = new HashSet();private Collection bids = new ArrayList();private Bid successfulBid;private ItemState state;private User approvedBy;private Date approvalDatetime;private Date created = new Date();/ getter/setter 方法省略不写,避免篇幅太长java 代码: public interfa

4、ce ItemDao public Item getItemById(Long id);public Collection findAll();public void updateItem(Item item); ItemDao 定义持久化操作的接口,用于隔离持久化代码。java 代码: public class ItemDaoHibernateImpl implements ItemDao extends HibernateDaoSupport public Item getItemById(Long id) return (Item) getHibernateTemplate().load

5、(Item.class, id);public Collection findAll() return (List) getHibernateTemplate().find(“from Item“);public void updateItem(Item item) getHibernateTemplate().update(item); ItemDaoHibernateImpl 完成具体的持久化工作,请注意,数据库资源的获取和释放是在 ItemDaoHibernateImpl 里面处理的,每个 DAO 方法调用之前打开 Session,DAO 方法调用之后,关闭 Session。(Sessi

6、on 放在 ThreadLocal 中,保证 一次调用只打开关闭一次)java 代码: public class ItemManager private ItemDao itemDao;public void setItemDao(ItemDao itemDao) this.itemDao = itemDao;public Bid loadItemById(Long id) itemDao.loadItemById(id);public Collection listAllItems() return itemDao.findAll();public Bid placeBid(Item ite

7、m, User bidder, MonetaryAmount bidAmount,Bid currentMaxBid, Bid currentMinBid) throws BusinessException if (currentMaxBid != null / Auction is activeif ( !state.equals(ItemState.ACTIVE) )throw new BusinessException(“Auction is not active yet.“);/ Auction still validif ( item.getEndDate().before( new

8、 Date() ) )throw new BusinessException(“Cant place new bid, auction already ended.“);/ Create new BidBid newBid = new Bid(bidAmount, item, bidder);/ Place bid for this Itemitem.getBids().add(newBid);itemDao.update(item); / 调用 DAO 完成持久化操作return newBid; 事务的管理是在 ItemManger 这一层完成的,ItemManager 实现具体的业务逻辑。

9、除了常见 的和 CRUD 有关的简单逻辑之外,这里还有一个 placeBid的逻辑,即项目的竞标。以上是一个完整的第一种模型的示例代码。在这个示例中, placeBid,loadItemById,findAll 等等业务逻辑统统放在 ItemManager 中实现,而Item 只有 getter/setter 方法。二、贫血模型简单来说,就是 domain ojbect 包含了不依赖于持久化的领域逻辑,而那些依赖持久化的领 域逻辑被分离到 Service 层。 Service(业务逻辑,事务封装) DAO - domain object 这也就是 Martin Fowler 指的 rich d

10、omain object一个带有业务逻辑的实体类,即 domain object 是 Item一个 DAO 接口 ItemDao 一个 DAO 实现 ItemDaoHibernateImpl 一个业务逻辑对象 ItemManagerjava 代码: public class Item implements Serializable / 所有的属性和 getter/setter 方法同上,省略public Bid placeBid(User bidder, MonetaryAmount bidAmount,Bid currentMaxBid, Bid currentMinBid)throws B

11、usinessException / Check highest bid (can also be a different Strategy (pattern)if (currentMaxBid != null / Auction is activeif ( !state.equals(ItemState.ACTIVE) )throw new BusinessException(“Auction is not active yet.“);/ Auction still validif ( this.getEndDate().before( new Date() ) )throw new Bus

12、inessException(“Cant place new bid, auction already ended.“);/ Create new BidBid newBid = new Bid(bidAmount, this, bidder);/ Place bid for this Itemthis.getBids.add(newBid); / 请注意这一句,透明的进行了持久化, 但是不能在这里调用 ItemDao,Item 不能对 ItemDao 产生依赖!return newBid; 竞标这个业务逻辑被放入到 Item 中来。请注意 this.getBids.add(newBid);

13、如果没有 Hibernate 或者 JDO 这种 O/R Mapping 的支持,我们是无法实现这种透明的持久化行为的。但是请注意,Item 里面不能去调用 ItemDAO,对 ItemDAO 产生 依赖!ItemDao 和 ItemDaoHibernateImpl 的代码同上,省略。java 代码: public class ItemManager private ItemDao itemDao;public void setItemDao(ItemDao itemDao) this.itemDao = itemDao;public Bid loadItemById(Long id) ite

14、mDao.loadItemById(id);public Collection listAllItems() return itemDao.findAll();public Bid placeBid(Item item, User bidder, MonetaryAmount bidAmount,Bid currentMaxBid, Bid currentMinBid) throws BusinessException item.placeBid(bidder, bidAmount, currentMaxBid, currentMinBid);itemDao.update(item); / 必

15、须显式的调用 DAO,保持持久化 在第二种模型中,placeBid 业务逻辑是放在 Item 中实现的,而 loadItemById 和 findAll 业务逻辑是放在 ItemManager 中实现的。不过值得注意的是,即使 placeBid 业务逻辑放在 Item 中,你仍然需要在 ItemManager 中简单的封装一层, 以保证对 placeBid 业务逻辑进行事务的管理和持久化的触发。这种模型是 Martin Fowler 所指的真正的 domain model。在这种模型中,有三个业务逻辑 方法:placeBid,loadItemById 和 findAll,现在的问题是哪个逻辑应

16、该放在 Item 中,哪个逻辑应该放在 ItemManager 中。在我们这个例子中, placeBid 放在 Item 中(但是 ItemManager 也需要对它进行简单的封装),loadItemById 和 findAll 是放在 ItemManager 中的。切分的原则是什么呢? Rod Johnson 提出原则是“case by case” ,可重用度高的,和domain object 状态密切关联的放在 Item 中,可重用度低的,和 domain object 状态没有密切关联的放在 ItemManager 中。经过上面的讨论,如何区分 domain logic 和 business logic,我想提出一个改进的区分原 则:domain logic 只应该和这一个 domain object 的实例状态有关,而不应该和一批 domain object 的状态有关;当你把一个

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号