Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a good idea to "migrate business logic code into our domain model"?

I am reading Hibernate in Action and the author suggests to move business logic into our domain models (p. 306). For instance, in the example presented by the book, we have three entities named Item, Bid, and User and the author suggests to add a placeBid(User bidder, BigDecimal amount) method to the Item class.

Considering that usually we have a distinct layer for business logic (e.g. Manager or Service classes in Spring) that among other things control transactions, etc. is this really a good advice? Isn't it better not to add business logic methods to our entities?

Thanks in advance.

like image 904
Behrang Avatar asked Apr 08 '10 02:04

Behrang


People also ask

Does business logic go in domain layer?

All invariant to use-cases logic (business entities, business workflow components, e.g. Domain model, Domain services) goes to the Domain layer (Domain logic). This layer is responsible for concepts of the business domain and business rules.

Should entities have business logic?

Yes. If the property's business logic all depends on the existing properties on the same model, it would be better to just add the property in the model.

What is the use of domain logic?

In computer software, business logic or domain logic is the part of the program that encodes the real-world business rules that determine how data can be created, stored, and changed.


1 Answers

As said

We have a distinct layer for business logic (usually called Service layer)

Domain-Driven-Design (DDD) states you should put business logic inside your domain model. And, believe me, it is really good. As said by POJO in Action book about Service layer

  • It is Use Case driven
  • It can define Transaction boundaries

Before

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

After

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

Your domain logic is show as follows

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

When using Domain-Driven-Design, your business logic lives in the right place. But, sometimes, it could be a good idea to define your business logic inside your Service layer. See here why

like image 111
Arthur Ronald Avatar answered Sep 22 '22 17:09

Arthur Ronald