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.
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.
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.
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With