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

Lam*_*bda 27 spring hibernate jpa

我正在阅读Hibernate in Action,作者建议将业务逻辑转移到我们的域模型中(p.306).例如,在经书给出的例子,我们有一个名为三个实体Item,Bid以及User和笔者建议的添加placeBid(User bidder, BigDecimal amount)方法的Item类.

考虑到平时我们(例如,对于业务逻辑的不同层ManagerService在Spring类),其他的东西控制交易中,等等.这是一个真正的好建议?是不是最好不要向我们的实体添加业务逻辑方法?

提前致谢.

Art*_*ald 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));
    }

}
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

您的域逻辑显示如下

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

}
Run Code Online (Sandbox Code Playgroud)

使用Domain-Driven-Design时,您的业务逻辑就位于正确的位置.但是,有时,在服务层内定义业务逻辑可能是个好主意.看到这里的原因

  • 为什么该项目会知道对其进行投标的规则?我会把它放在一个处理规则的不同模块中,并从投标过程中抽象出来.每次我们发展规则时,我都不想更改Item类.但我仍然会在Item.placeBid(...)方法中调用这些规则. (4认同)
  • @Stephane:一个项目知道如何在它上面制作比特因为*这就是一个项目用于*!它是面向对象世界观下项目本质的基本组成部分. (2认同)

Pab*_*jim 9

其中引用最多的文章之一是:

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

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

或引用:

"一般来说,你在服务中发现的行为越多,就越有可能剥夺自己对域模型的好处.如果你的所有逻辑都在服务中,你就会使自己失明."