Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Organise a Domain Driven Design Project?

People also ask

Which approach we can use for Domain-Driven Design?

Domain-Driven Design is a concept introduced by a programmer Eric Evans in 2004 in his book Domain-Driven Design: Tackling Complexity in Heart of Software. It is an approach for architecting software design by looking at software in top-down approach.

Is Domain-Driven Design still relevant?

Domain Driven Design (DDD) has recently gained additional popularity, as evidenced by new books, conference talks, and even complete conferences dedicated to it), and lots of trainings – including some by our very own colleagues here at INNOQ.

What is DDD approach?

Domain-driven design (DDD) is a software development philosophy centered around the domain, or sphere of knowledge, of those that use it. The approach enables the development of software that is focused on the complex requirements of those that need it and doesn't waste effort on anything unneeded.


I try to keep things very simple whenever I can, so usually something like this works for me:

Myapp.Domain - All domain specific classes share this namespace

Myapp.Data - Thin layer that abstracts the database from the domain.

Myapp.Application - All "support code", logging, shared utility code, service consumers etc

Myapp.Web - The web UI

So classes will be for example:

  • Myapp.Domain.Sales.Order
  • Myapp.Domain.Sales.Customer
  • Myapp.Domain.Pricelist
  • Myapp.Data.OrderManager
  • Myapp.Data.CustomerManager
  • Myapp.Application.Utils
  • Myapp.Application.CacheTools

Etc.

The idea I try to keep in mind as I go along is that the "domain" namespace is what captures the actual logic of the application. So what goes there is what you can talk to the "domain experts" (The dudes who will be using the application) about. If I am coding something because of something that they have mentioned, it should be in the domain namespace, and whenever I code something that they have not mentioned (like logging, tracing errors etc) it should NOT be in the domain namespace.

Because of this I am also wary about making too complicated object hierarchies. Ideally a somewhat simplified drawing of the domain model should be intuitively understandable by non-coders.

To this end I don't normally start out by thinking about patterns in much detail. I try to model the domain as simple as I can get away with, following just standard object-oriented design guidelines. What needs to be an object? How are they related?

DDD in my mind is about handling complex software, but if your software is not itself very complex to begin with you could easily end up in a situation where the DDD way of doing things adds complexity rather than removes it.

Once you have a certain level of complexity in your model you will start to see how certain things should be organised, and then you will know which patterns to use, which classes are aggregates etc.

In my example, Myapp.Domain.Sales.Order would be an aggregate root in the sense that when it is instanced it will likely contain other objects, such as a customer object and collection of order lines, and you would only access the order lines for that particular order through the order object.

However, in order to keep things simple, I would not have a "master" object that only contains everything else and has no other purpose, so the order class will itself have values and properties that are useful in the application.

So I will reference things like:

Myapp.Domain.Sales.Order.TotalCost

Myapp.Domain.Sales.Order.OrderDate

Myapp.Domain.Sales.Order.Customer.PreferredInvoiceMethod

Myapp.Domain.Sales.Order.Customer.Address.Zip

etc.


I like having the domain in the root namespace of the application, in its own assembly:

Acme.Core.dll [root namespace: Acme]

This neatly represents the fact that the domain is in scope of all other portions of the application. (For more, see The Onion Architecture by Jeffrey Palermo).

Next, I have a data assembly (usually with NHibernate) that maps the domain objects to the database. This layer implements repository and service interfaces:

Acme.Data.dll [root namespace: Acme.Data]

Then, I have a presentation assembly declaring elements of my UI-pattern-of-choice:

Acme.Presentation.dll [root namespace: Acme.Presentation]

Finally, there is the UI project (assuming a web app here). This is where the composition of the elements in preceding layers takes place:

Acme.Web [root namespace: Acme.Web]


Although you're also a .Net developer, the Java implementation reference of the cargo app from DDD by Eric Evans and Citerus is a good resource.

In the doc'd code, you can see the DDD-organization into bounded contexts and aggregates in action, right in the Java packages.

Additionally, you might consider Billy McCafferty's Sharp Architecture. It's an ASP.Net MVC, NHibernate/Fluent NHibernate implementation that is built with DDD in mind.

Admittedly, you will still need to apply a folder/namespace solution to provide the contexts. But, couple the Evans approach with #Arch and you should be well on your way.

Let us know what you are going with. I am on the same path as well, and not far from you!

Happy coding,

Kurt Johnson


Your domain probably have a name, so you should use this name as namespace.

I usally put repository implementation and data access details in a namespace called Persistance under the domain namespace.

The application use its own name as namespace.