Article: Domain Driven Design and Development In Practice
Domain-Driven Design is a subject where there currently are very few examples of how to actually do it in practice. In this article, Srini Penchikala gives you guidelines, practices, frameworks and tools that technical leads and architects can use in the effort of implementing a system in a Domain-Driven way.
From the article:
Domain Driven Design and Development is also influenced by several architectural, design, and implementation aspects such as:
- Business Rules
- Persistence
- Caching
- Transaction Management
- Security
- Code Generation
- Test Driven Development
- Refactoring
This article talks about how these different factors affect the implementation project throughout its lifecycle and what the architects should look for in realizing a successful DDD implementation. I will start off with a list of characteristics a typical domain model should have, and when to use a domain model in an enterprise (versus not using a domain model at all or using an anemic domain model).
After that initial effort, Srini guides you though Project Management, Architecture, Design, Development, Unit Testing/Continous Integration and Deployment of a domain driven application. A sample applictaion is provided with the article.
If you want to understand how annotations, dependency injection, code generation, transaction management, data transfer objects and many other things fits into a DDD-context - read the full article on Domain Driven Design and Development In Practice.
It's wonderful!
by
Geng Laurence
One observation.
by
Leonard Petrica
E.g.
public void add() {
loanRepository.add(this);
}
No asserts in the tests
by
Peter Bona
Mixed feelings
by
Yuriy Zubarev
What's the advantage of
loan.add(newLoan);
over
newLoan.add();for example?
You have "loan" object auto-wired in this class for a sole purpose of persisting "newLoan" as it seems. A domain object is used as a service to persist another domain object of the same type. May be I'm missing something but it doesn't feel quite right.
Thank you.
Re: It's wonderful!
by
Geng Laurence
Re: It's wonderful!
by
Srini Penchikala
What am I missing?
by
Rob Rudin
And am I the only one who finds a method such as ProductRate.findProductRates() to be a bit awkward in a grammatical sense? Does it really make sense to ask an instance of an object to return a list of instances of its class type? Does anyone actually talk like that in their business domain?
I also found the rhetoric at the top of the article to be conspicuously absent of any proof. "Not investing in a domain model" will "not give the company a competitive advantage over other companies because implementing business requirement changes in this architecture takes too long"? Really? Where's your evidence to back this up?
I've used Spring/Hibernate/AOP/DI/TDD/CI/insert-your-favorite-buzzword/etc on a daily basis for almost the past 5 years. I've followed the DDD movement with some curiousity, but if this code sample is indicative of what it amounts to, I honestly don't understand what the fuss is about.
Not even close to DDD
by
Kaushik Selvaraj
>> Ramnivas Laddad where he made the assertion that DDD cannot be implemented without help of AOP and DI.
You got it wrong. He said DDD cannot be "adequately implemented" without AOP. I have posted on how you could use DDD without AOP here .
In your example code, none of your entities exhibit any encapsulation. Why do nearly every field have a getter and setter exposed ? There is absolutely no domain business methods in them. By just exposing CRUD methods in addition to getter/setters how can you even call these domain objects? As a previous commenter had posted, are'nt these still anemic?
Main concept behind Domain Driven Design is adding power to your domain classes which you have not brought out at all. The examples are woefully shallow and cannot be called as DDD examples at all. It is more an example of using spring's DI to inject repositories into DDD. This article does not do justice to elegance and simplicity of DDD.
PS: Next time do some proper research before suggesting matching up various technologies like OSGi with DDD/AOP/Spring etc. If you had any experience implementing either DDD or OSGi you would know that using AOP in OSGi is severly limited. For e.g. aspects have to exist in every single bundle where it has to be applied.
Re: What am I missing?
by
Phatthana Sitthideth
nice article
@Rob
Yeah i know exactly what you mean by "what the fuss is about".
From my experiences 80% of these Spring/Hibernate/AOP/DI/TDD/CI/insert-your-favorite-buzzword/etc projects don't need
DDD, it's just CRUD stuff.
As Eric Evans told me, DDD is for the 10%-20% percent of a system -> the truely complicated sh*t.
That logic should be implemented by developers with strong design skills with the help of open minded business analyst -> DDD is a sophisticated
technique for that.
My point is people tend to "ddd"-everthing, i.e.
if anyone tells you: "yeah our system is completely build upon/using DDD".....yeah ok, dream on
None the less i think DDD is great stuff and definitely changes your view of perspective on design/oo/teamwork.
Cheers
Phatthana
It *completely* misses the point...
by
Ronald Miura
It seems that the author thinks a 'rich domain' is just 'inject DAOs into hibernate-mapped objects'...
Looking at the source code, you can see the domain is just the plain old anemic model, with DAOs (disguised as Repositories) injected.
At least in the examples, it doesn't make sense to use an instance of an entity to 'find' others, which don't even have any relation (but its class) to the first. It is just being used as a Repository (yeah, 'loan.add(newLoan)' IS stupid). And the domain logic, which should be inside the entities, are externalized to the services, which are just glorified procedures.
Where is the 'insight'? Where is the 'objects model the business'? Where is the 'ubiquitous language'?
If you are looking for a DDD example, take a look at the TimeAndMoney (timeandmoney.domainlanguage.com/) library. No, it doesn't have a 'persistence layer', but DDD is not about these, it's about capturing the business into objects. It isn't about CRUD, it's about creating a language in code that matches the language in business (the core of it). It's not about DI or Spring or Hibernate, it's about good, careful, insightful, relentless design.
Re: It *completely* misses the point...
by
Dustin Woods
If you are looking for a DDD example, take a look at the TimeAndMoney (timeandmoney.domainlanguage.com/) library. No, it doesn't have a 'persistence layer', but DDD is not about these, it's about capturing the business into objects. It isn't about CRUD, it's about creating a language in code that matches the language in business (the core of it). It's not about DI or Spring or Hibernate, it's about good, careful, insightful, relentless design.
"TimeAndMoney" makes a nice example of a library but it is far from any help at all when building an entire application. I personally appreciate samples like these because is shows the struggle that people have trying to apply DDD to real world problems. Without seeing samples that have gotten the blessing of being DDD maybe DDD is for small libraries only and doesn't apply to real world problems. It's easy to criticize Srini for sharing an interpretation of DDD without opening yourself up to criticism with any sample of your own.
Re: It *completely* misses the point... Not!
by
Geert Pante
If you are looking for a DDD example, take a look at the TimeAndMoney (timeandmoney.domainlanguage.com/) library. No, it doesn't have a 'persistence layer', but DDD is not about these, it's about capturing the business into objects. It isn't about CRUD, it's about creating a language in code that matches the language in business (the core of it). It's not about DI or Spring or Hibernate, it's about good, careful, insightful, relentless design.
"TimeAndMoney" makes a nice example of a library but it is far from any help at all when building an entire application. I personally appreciate samples like these because is shows the struggle that people have trying to apply DDD to real world problems. Without seeing samples that have gotten the blessing of being DDD maybe DDD is for small libraries only and doesn't apply to real world problems. It's easy to criticize Srini for sharing an interpretation of DDD without opening yourself up to criticism with any sample of your own.
Hear, hear!
Having fooled around a bit myself with DDD and Java, I hoped to find a way to do three things at once. Do DDD, avoid having to write a lot of duplicate boiler plate code, and keep Spring/Hibernate/JUnit best practices. In doing so, I independently did the same discovery as mr. Laddad: that AOP could be the missing link.
Indeed, Domain Driven Design is not tied to particular use of any framework, but if Hibernate allows you to auto-generate DAO's and Repositories, and Spring's @Configurable annotations with AOP allows you to auto-generate Factories, why wouldn't you go with the flow?
Srini, I haven't checked your sample code thoroughly, but if you managed to get it all connected and working, you did an excellent job, and it could provide the basis of a lot of our future projects' designs.
Re: No asserts in the tests
by
Srini Penchikala
Re: Mixed feelings
by
Lindsay Holman
It is extremely important that when undertaking this approach, the principle are kept in mind and adhered to, as there are pitfalls waiting around the corner for those who don't.
As far as this being more an anaemic model, it is just because of the lack of hard core business logic, and in itself isn't a problem. I don't see a problem with creating an anaemic model from a DDD focus - at least the focus remains on the ubiquitous language.
I have just been involved in rescuing an SOA development. SOA services can be equated to Eric Evans' idea of an application service. This is essentially a gateway into the business logic, or the domain model. The development in question used JAXB to generate classes from an xsd defining the service interface, and to populate objects from the xml message. The services were extremely long, procedural, untestable methods which utilised the generated classes. There was a layer of DAOs which also used these generated classes!! Something to shift focus onto the domain and reinforce the fact that the SOA service is a thin layer whose responsibility is integration - not business logic, would have avoided this.
I find it perplexing the number of SOA oriented developers who dismiss the idea of a rich domain model. It seems to me to highlight a lack of understanding of the very essence of the architecture they are implementing. These two approaches are not mutually exclusive - there are distinct responsibilities in each layer.
Anyway, sorry about the waffle. This is my first post - hi everyone :)
Domain-Obects Java Classes not so intuitive
by
venkataramana madugundu
Re: Mixed feelings
by
Srini Penchikala
Re: It's wonderful!
by
Srini Penchikala
Re: It's wonderful!
by
James Bao
Re: Mixed feelings
by
Yuriy Zubarev
Re: Mixed feelings
by
Lindsay Holman
I don't agree with you here. Circular dependencies just signify poor design. You can quite legitimately have a domain object deal with persistence without circular references. Note, a domain object which is an entiy should not be responsible for it's own persistence, a repository object should (Not a DAO - this is rooted in deficiencies of EJB).
The underlying priciple is that the domain model is supposed to be a model of your business. Does it make sense within that domain that you need to store and retrieve entities (say, a loan). Absolutely yes, so this should be handled by a domain object. When you do store a loan in the real world, do you get the loan to do it? No, you stick it in some sort of repository. You can see here, the domain model is modelling the real world.
Typically, as per good design practice, the repository will be comprise an implementation and an interface. All domain type references are confined to the domain layer (model).
The repository will then farm off the technology specific aspects to an object in the infrastructure layer. This can be achieved through extension, delegation, template pattern etc. Whatever way you choose, avoiding cirulcar references is just down to good design.
Typically in a hibernate environment for example, you would have a generic persistence object, or a base persistence object for instance, which takes a class type and an object. Though not really correct, but in line with many codebases, let's call this the HibernateGenericDao class. It implements the interface GenericDao which defines the method "add(String className, Object value)". In the domain model, we have a LoanRepositoryImpl class which wraps GenericDao and implements LoanRepository. LoanRepository defines the method add(Loan loan). The LoanRepositoryImpl.add(Loan loan) implementation delegates to genericDao.add(Loan.getClass().getName(), loan). The HibernateGenericDao then takes care of the hibernate specifics.
LoanRepository, Loan and LoanRepositoryImpl are members of the domain layer. GenericDao and HibernateGenericDao are in the infrastructure layer. The domain layer knows about the infrastructure layer, but the infrastructure layer knows nothing of the domain layer. Perfectly layered, no circular references. If we want to change the persistence mechanism, we plug in a different implementation of GenericDao into LoanRepositoryImpl.
Then, when we want to add a loan, a ui object may collect the details, an application service object collates the details into a loan object, and call loanRepository.add(loan). I don't see what is not clear about this implementation where persistence is handled by a domain object.
Re: It's wonderful!
by
Lindsay Holman
Misleading
by
Ilya Boyandin
Re: What am I missing?
by
Srini Penchikala
Re: It's wonderful!
by
Srini Penchikala
Re: It's wonderful!
by
Lindsay Holman
I really think having repositories and an infrastructure layer, and dao's and a data access layer is a massive overcomplication of a simple problem. As far as why persistence belongs in the domain model (re your reply to James), the simple explanation somes from the domain we are trying to model. Given a traditional paper based office, we have a new client say, we collect their details (at least enough to identify them), we create some sort of file for them, then we store them in a repository of some sort, organised in such a way that we can easily retrieve those details. This obviates the necessity for a repository in the domain layer.
The repository should farm off technical aspects of the persistence to an object in the infratructure layer. There is no need for DAO's, or a data access layer. Data access layers are all about removing that functionality from the domain, which is specifically what we do not want to do. DAO's only came into being because of the shortcomings of the EJB spec. Nobody uses Entity EJB's anymore, so please stop using DAO's.
DDD on 3 tiers (Differents JVM)
by
iury ribeiro
Great discussion! I enjoyed a lot.
I would like to clarify the following case:
As you said that the CRUD methods belong to entity objects(domain object)and to get the others objects through the navigation, So I released in the case where the application is split on 2 JVM accessing a stateless session bean, We need to convert ours POJO on Proxy Pojo to access the facede session.
Am I right?
Regards,
Iury
Sculptor
by
Patrik Nordwall
Sculptor is an Open Source tool that applies the concepts from Domain-Driven Design and Domain Specific Languages.
You express your design intent in a textual specification, from which Sculptor generates high quality Java code and configuration. Sculptor takes care of the technical details, the tedious repetitive work, and let you focus on delivering more business value – and have more fun.
The generated code is based on well-known frameworks, such as Spring Framework, Spring Web Flow, JSF, Hibernate and Java EE.
The DSL and the code generation drives the development and is not a one time shot. It is an iterative process, which can be combined with Test Driven Development and evolutionary design.
Sculptor home: fornax-platform.org/cp/x/aAQ
Re: It's wonderful!
by
iury ribeiro
May you clarify my question?
In the following case: where the application is split on 2 (tomcat and jee server) JVM accessing a stateless session bean, We need to convert ours POJO on Proxy to access the facade session. Am I right?
Re: It's wonderful!
by
Lindsay Holman
I'm not entirely clear on exactly what it is you need to do, but I'll take a guess and put something forward.
Typically, our front end will call a SLSB Facade on tier 2. The traditional, and still somewhat sensible way of doing this is implementing an application service via the SLSB. If for instance we want to get a Loan object, tier 1 would call the tier 2 SLSB application service. The application service would have access to the domain model, querying the LoanRepository to find the required Loan object and passing it back.
This type of arrangement allows you to incorporate an SOA implementation alongside the rich domain model. The SLSBs can be thought of as gateways to the model.
Re: DDD on 3 tiers (Differents JVM)
by
Srini Penchikala
Re: Sculptor
by
Srini Penchikala
Re: It's wonderful!
by
Mattias Fagerström
Re: It's wonderful!
by
Srini Penchikala
Naming throwing
by
Eduardo Miranda
Do you really need all these tools to develop a DDD application?
Re: I *completely* agree
by
Dimitris Menounos
Re: Naming throwing
by
Srini Penchikala
Re: I *completely* agree
by
Srini Penchikala
What about the Grails approach?
by
Goran Oberg
What I like about Grails and more specifically the GORM, is the domain centric approach to data access. No daos and no repositories to be implemented, just plain domain classes! A dynamic language like Groovy giving the possibility to constructs like User.findAllByNameAndTimeBetween(name,start,end) without implementing the finder method (dynamically created), just adds to the plus side.
Of course Grails have downsides as well (some of them quite serious to), but it will not stop me from using Grails on certain projects and it will definitely give me some architectural inspiration when I'm back on my next Spring-hibernate project.
Just a small comment on the source code in the article:
Shouldn't finder related methods be static and operations like save act on the object it self?
Re: What about the Grails approach?
by
Soner Dastan
I read several articles about DDD but still I could not find out, when to use the DDD approach
makes sense and why the "anemic" principle is an anti-pattern. I can not see that using the anemic model causes issues to call it an anti-pattern.
In the anemic model we also have the separation of responsibilities and so on.
What are the differences except that the domain model in case of DDD includes business logic?
Both models has a similar architecture layering.
Is there an article comparing both approaches with their pro and contras and showing sample use cases where which design style should be used?
Re: What about the Grails approach?
by
Srini Penchikala
DDD and agile
by
Nima n
Re: DDD and agile
by
Srini Penchikala
Domain objects should not call CURD operations
by
Sandeep akhare
Article's starting was good and even i sent this link to my friends saying great implementation for DDD. But when we saw the code in the domain entities method you are calling CURD operation which smells some wrong implementation. You are neglecting basic rule of domain driven design which says that your domain should be persistance ignorent.
Please let me know if my understanding is wrong. What should is say to my friends whome i sent this link .
Re: Mixed feelings
by
H S
First thanks a lot for good article. I followed through your article and reviews of different people.
I still have one question (as Lindsay said) and you also agreed that persistence should be the responsibility of the repository rather than the entity. We need one domain object which would be acting as a (service) creating a entity and persisting the entity to DB.
e.g
Loan newLoan = CreateLoanWithBusinessRequirements()
loanRepository.save(newLoan)
Which domain object will you add this kind of behavior, and do we require such domain object for each entity in our domain?
don't inject repository into model
by
Peng Sunny
Domain Layer uses the Infrastructure Layer. The layer below it.
by
Roy Oliver
Could some of you attempt to explain this?
I'm seriously confused.
A comment on the sample application
by
Enrique Molinari
Very bad example application, practically anti-DDD example
by
Georgi Danov
Educational Content
Clojure in the Field
Stuart Halloway May 23, 2013
Tuning the Size of Your Thread Pool
Kirk Pepperdine May 23, 2013




Hello stranger!
You need to Register an InfoQ account or Login to post comments. But there's so much more behind being registered.Get the most out of the InfoQ experience.
Tell us what you think