我正在阅读《 Hibernate in Action》,作者建议将业务逻辑移入我们的域模型(第306页)。例如,在本书提供的示例中,我们有三个名为ItemBidUser的实体,并且作者建议向placeBid(User bidder, BigDecimal amount)类添加Item方法。

考虑到通常我们通常在业务逻辑上有一个独特的层(例如Spring中的ManagerService类),除其他事项外,该层还控制事务等,这真的是一个好建议吗?不向我们的实体添加业务逻辑方法不是更好吗?

提前致谢。

最佳答案

如前所述



域驱动设计(DDD)指出,您应该将业务逻辑放入域模型中。而且,相信我,这真的很好。正如POJO在《行动》一书中有关服务层的说法

  • 是用例驱动的
  • 它可以定义事务边界

  • 之前
    @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));
         }
    
    }
    

    使用域驱动设计时,您的业务逻辑将放在正确的位置。但是,有时是,在Service层内部定义业务逻辑可能是一个好主意。见here为什么

    关于hibernate - “migrate business logic code into our domain model”是个好主意吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2597219/

    10-10 02:46