Monday, May 24, 2010

On domain-driven design...

One of the design principles (of any enterprise application) which I found difficult to make up my mind is: (Anemic domain models + Service Objects) Vs. Fully featured domain objects.

Most of my business (application) layer consists of many Service objects (DAOs, Session Beans, BOs, Delegates, Facades etc) AND many POJO domain objects. Here the domain objects are nothing but data holders. There is no business logic in it. Arguably, this is an application of "separation of concerns", where business and/or data access logic is separated from data holders (in other words, Transfer Objects or Value Objects).

Whereas, there is a counter argument from another side (mostly the proponents of Domain- Driven Development (DDD)) that separating domain objects from its operations is nothing but going back to procedural style of programming. I don't know if I necessarily agree with it. Frameworks like Hibernate (even JPA) allows us to embed custom SQL's inside the domain model. In my mind that is a 'mixing' of concerns. Also, imagine a method called sell() inside a Book object. Does a book know how to sell it? Also, Book has an existence without a sell()functionality. In cases like this, I prefer a BookServiceImpl.sell(book) andBookServiceImpl.calculatePrice(book) rather than Book.sell() and Book.calculatePrice().

This is not to totally dismiss the other argument. If we are developing software for a rapidly changing business domain, from a maintainability perspective, DDD approach may sound attractive. For example, when the way they sell book changes , the place it requires the code change is the Book.sell() method, where as, if we are to change the service method, it might affect various other sub-systems. But when Book object requires another domain object (e.g: CreditCard object) to do its selling, things become complicated. Yes, we can inject CreditCard object to Book object, but effectively we are introducing a level of coupling.