我正在阅读 Hibernate in Action,作者建议将业务逻辑移动到我们的域模型中(第 306 页)。例如,在本书提供的示例中,我们有三个实体,分别名为 Item
、Bid
和 User
,作者建议添加一个placeBid(User bidder, BigDecimal amount)
方法到 Item
类。
考虑到通常我们有一个独特的业务逻辑层(例如 Spring 中的 Manager
或 Service
类),其中包括控制事务等,这真的是一个好建议?不给我们的实体添加业务逻辑方法不是更好吗?
提前致谢。
最佳答案
如前所述
We have a distinct layer for business logic (usually called Service layer)
领域驱动设计 (DDD) 指出您应该将业务逻辑放入您的领域模型中。而且,相信我,它真的很棒。正如 POJO 在关于 Service 层的 Action book 中所说的那样
- 它是用例驱动的
- 可以定义事务边界
之前
@Service
public class BidServiceImpl implements BidService {
@Autowired
private ItemRepository itemRepository;
public void placeBid(Integer itemId, User bidder, BigDecimal amount) {
Item item = itemRepository.getById(itemId);
if(amount.compareTo(new BigDecimal("0.00")) <= 0)
throw new IllegalStateException("Amount must be greater than zero");
if(!bidder.isEnabled())
throw new IllegalStateException("Disabled bidder");
item.getBidList().add(new Bid(bidder, amount));
}
}
之后
@Service
public class BidServiceImpl implements BidService {
@Autowired
private ItemRepository itemRepository;
public void placeBid(Integer itemId, User bidder, BigDecimal amount) {
// itemRepository will retrieve a managed Item instance
Item item = itemRepository.getById(itemId);
item.placeBid(bidder, amount);
}
}
您的域逻辑如下所示
@Entity
public class Item implements Serializable {
private List<Bid> bidList = new ArrayList<Bid>();
@OneToMany(cascade=CascadeType.ALL)
public List<Bid> getBidList() {
return this.bidList;
}
public void placeBid(User bidder, BigDecimal amount) {
if(amount.compareTo(new BigDecimal("0.00")) <= 0)
throw new IllegalStateException("Amount must be greater than zero");
if(!bidder.isEnabled())
throw new IllegalStateException("Disabled bidder");
/**
* By using Automatic Dirty Checking
*
* Hibernate will save our Bid
*/
item.getBidList().add(new Bid(bidder, amount));
}
}
使用领域驱动设计时,您的业务逻辑位于正确的位置。但是,有时,在服务层中定义业务逻辑可能是个好主意。见 here为什么
关于hibernate - "migrate business logic code into our domain model"是个好主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2597219/