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

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

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

Заранее спасибо.

Ответы [ 3 ]

14 голосов
/ 08 апреля 2010

Как сказал

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

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

}

* После 1021 *

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

9 голосов
/ 16 апреля 2010

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

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

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

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

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

0 голосов
/ 24 сентября 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...