views:

1013

answers:

5

Hi Guru's,

I've started learning about DDD and wanted to know how others have organised their projects.

I've started off by organising around my AggregateRoots:

MyApp.Domain (namespace for domain model)

MyApp.Domain.Product
- Product
- IProductService
- IProductRepository
- etc

MyApp.Domain.Comment
- Comment
- ICommentService
- ICommentRepository
- etc

MyApp.Infrastructure
- ...

MyApp.Repositories
- ProductRepository : IProductRepository
- etc

The problem i've bumped into with this is that i have to reference my domain product as MyApp.Domain.Product.Product or Product.Product. I also get a conflict with my linq data model for product....I have to use ugly lines of code to distiguish between the two such as MyApp.Domain.Product.Product and MyApp.Respoitories.Product.

I am really interested to see how others have organised their solutions for DDD...

I am using Visual Studio as my IDE.

Thanks alot.

+4  A: 

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.

Console
Makes sense...Order and Customer are you AggRoots right? So when you reference your Order object you have to do it like: Myapp.Domain.Sales.Order.Order??
Yes and no - I extended my example a little, as the comments section is a bit too short.
Console
A: 

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.

Think Before Coding
+3  A: 

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]

Bryan Watts
A: 
bingle
+2  A: 

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

Kurt Johnson