views:

227

answers:

4

I'm starting a new project; I wish to follow a DDD approach. We have talked to the business and achieved some insight into the domain in some detail (internet TV).

The team is five strong and distributed. We have adopted the repository pattern for data-access. We are following a service-based approach overall; services are responsible for performing operations, and we will expose some operations via a REST API, and some via our own client applications.

The people that do not have experience with ORMs (not that I have a massive amount either, at present) wish to model the entities without relationships between them, with the rationale that this forces the developers who use the Repositories to know precisely what effect they are having on the database. I am trying to point out that this will end up with a very chatty set of services, more code to maintain and test, and a domain model that fundamentally misses the point. I don't think this is a good approach, and neither do any of the people I've talked to about it.

Their desire for the implementation of this approach is Linq2SQL under the repository-facade. This requires a second model, a mapping class/layer between it and the domain model, and much duplication in the repositories because it doesn't appear to be possible (that we've seen so far) to write a generic repository. It also isn't possible to map L2S entities that leverage inheritance (which means that EVERY entity must have properties for created-on, created-by, etc)

1st question: Can anyone offer me any advice about how to change their minds? I'm in the process of writing a side-project which uses NHibernate, which of course supports the DDD-approach well, on the basis that "Show me the code" is a powerful argument.

2nd question: What sorts of thing should I attempt to demonstrate in my NHibernate-using on-my-own-time side-project? I am new to it; one of their dislikes for NHibernate is the learning curve and the requirement for XML; my counter-argument is that it's a powerful tool, and Fluent NHibernate eliminates the need for XML. They still don't like it.

+1  A: 

Can't give you specifics since I haven't used hibernate. but the general truth that applies to almost everything like this is:

"Make everything as simple as possible, but not simpler."
   -- Albert Einstein 

So my opinion would be to use the minimal connections possible to keep the system well defined. And avoid trying to connect everything because it'll bite you in the back (remember the principle of loose coupling in programming)

Robert Gould
+3  A: 

Have you looked at the concept of aggregate roots in DDD? Basically you only request aggregate roots out of repositories and the whole aggregate is loaded. The aggregate has everything it needs to do the required operation, so that would eliminate your concern of chattiness and would also address your team's concern of being explicit about what is loaded.

In your side project, demonstrate a repository based on an aggregate root that loads the entire aggregate. This is fairly straight forward code and is very explicit in its intentions. Unfortunately you still have to ride the NHibernate learning curve, but there will be less "magic" going on if you use this approach.

Stefan Moser
A: 

It seems that your team are using the ORM just as a way of mapping the database to a set of concrete classes in order to make the code a bit nicer. If you think of creating a Domain Model instead and not just an abstracted database model then it would be apparent you should include relationships. How data is loaded behind the scenes is another matter.

Craig
+1  A: 

From your description I am guessing each service you are building is centred around a particular entity and when you're domain model wants different entities it needs to use a different service.

If this is the case I would suggest that the service are too finely grained. I would suggest building the interfaces for your services around processes which need to be accomplished, with the domain model part of the implementation of these services. It is my understanding that SOA advocates exposing a system as a set of services, however the internal interaction of components of a single system should not be services.

This approach leads to a rich domain model, using Aggregate roots as a means of relating entities together and a basis for the repositories, with the services sitting on top of this exposing coarsely grained behaviour rather than basic interaction with any single entity. The client applications, which are internal to your system can provide this (using the same domain model).

If the entities in your model are related and these relationships are important to the behaviour of the system then these relationships should be enforced (so the system reflects the domain being modelled), this will be difficult to do if each entity is independent, especially if they are services.

You will end up with a system where all of the entity services need to call each other (creating lots of coupling, increasing change management overhead etc) or you won't be able to enforce the relationships which will mean diluting your model and potentially resulting in inconsistent behaviour or missing data.

This will fundamentally come down to the base principles of High Cohesion and Low Coupling, which are opposing forces, it is necessary to try and balance them in a solution. If you have no relationship (or implicit ones) then you gain low coupling at the cost of cohesion and possible create maintenance issues if there are really relationships that aren't represented or increase the dependencies at a higher level. If you enforce too many relationships strongly you will end up with your domain model becoming a ball of mud and becoming unmanageable. Specific advice on this is difficult, however generally I would start by building a model with aggregates, concentrating on the relationships internal to the aggregate and review the model frequently.

Specifically on NHibernate I would suggest demonstrating the clean abstraction that it provides, the reduction in code needed, the easy configuration without changing code and the amount of provided functionality e.g. identity maps and units of work etc.

marcj