“将业务逻辑代码迁移到我们的域模型中”是一个好主意吗?

时间:2010-04-08 02:33:43

标签: hibernate spring jpa

我正在阅读Hibernate in Action,作者建议将业务逻辑转移到我们的域模型中(p.306)。例如,在本书提供的示例中,我们有三个名为ItemBidUser的实体,作者建议在placeBid(User bidder, BigDecimal amount)方法中添加Item方法{1}}上课。

考虑到通常我们有一个独特的业务逻辑层(例如Spring中的ManagerService类),其中包括控制事务等,这真的是一个很好的建议吗?是不是最好不要向我们的实体添加业务逻辑方法?

提前致谢。

3 个答案:

答案 0 :(得分:14)

如上所述

  

我们有一个独特的业务逻辑层(通常称为服务层)

域驱动设计(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));
     }

}

使用Domain-Driven-Design时,您的业务逻辑生活在正确的位置。但是,有时,在服务层内定义业务逻辑可能是个好主意。请参阅here原因

答案 1 :(得分:9)

最引用的文章之一是:

马丁福勒的“贫血领域模型”。 非常值得一读:http://martinfowler.com/bliki/AnemicDomainModel.html

一般要点是,如果您的域模型纯粹是没有行为的数据,那么您就失去了OO设计的许多好处。

或引用:

“一般而言,您在服务中发现的行为越多,您就越有可能剥夺自己对域模型的好处。如果您的所有逻辑都在服务中,那么您就会使自己失明。” / p>

答案 2 :(得分:0)

我个人喜欢贫血模型 - 数据是数据,代码是代码;但也有例外。

归结为'密度':如果你有大量的服务与一些域对象交互;将一些通用业务逻辑放在您的域模型中是有意义的,因此它成为服务的一部分。如果您有一些与许多域对象交互的服务,那么优先于贫域模型而不是胖域模型。

我发现如果我在多个上下文中使用我的域对象(例如,我在客户端和服务端使用相同的域对象),那么业务逻辑通常会妨碍 - 因为它必须适用于所有情况。