Подтвердить что ты не робот

Является ли хорошей идеей "перенести код бизнес-логики в нашу модель домена"?

Я читаю Hibernate in Action, и автор предлагает переместить бизнес-логику в наши модели домена (стр. 306). Например, в примере, представленном в книге, мы имеем три объекта с именем Item, Bid и User, и автор предлагает добавить метод placeBid(User bidder, BigDecimal amount) в класс Item.

Учитывая, что обычно у нас есть отдельный уровень для бизнес-логики (например, Manager или Service классов в Spring), который, среди прочего, контролирует транзакции и т.д., это действительно хороший совет? Разве не лучше не добавлять методы бизнес-логики к нашим объектам?

Спасибо заранее.

4b9b3361

Ответ 1

Как сказано

У нас есть отдельный слой для бизнес-логики (обычно называемый уровнем сервиса)

Domain-Driven-Design (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 ваша бизнес-логика живет в нужном месте. Но иногда, было бы неплохо определить вашу бизнес-логику внутри вашего уровня сервиса. См. здесь почему

Ответ 2

Одна из наиболее цитируемых статей по этому вопросу:

"Модель анемичного домена" Мартина Фаулера. Хорошо стоит прочитать: http://martinfowler.com/bliki/AnemicDomainModel.html

Общий смысл заключается в том, что ваша модель домена - это чисто данные без какого-либо поведения, тогда вы потеряли много преимуществ дизайна OO.

или процитировать:

"В целом, чем больше вы найдете поведение в сервисах, тем больше вероятность того, что вы будете ограбить себя от преимуществ модели домена. Если ваша логика в сервисах, вы лишили себя слепых".

Ответ 3

Лично мне нравится анемичная модель - данные - данные, код - код; но есть исключения.

Это сводится к "плотности": если у вас есть большое количество сервисов, которые взаимодействуют с несколькими объектами домена; имеет смысл поставить часть общей бизнес-логики в вашу модель домена, поэтому она становится частью сервиса. Если у вас есть несколько сервисов, которые взаимодействуют с большим количеством объектов домена, то предпочитают анемичную модель над богатыми объектами домена.

Я обнаружил, что если я использую свои объекты домена в нескольких контекстах (например, я использую те же объекты домена на стороне клиента и на стороне службы), что бизнес-логика часто мешает - поскольку она должна применяться в все контексты.