Is DDD not appropriate for the website or should I introduce a Query Layer

domain-driven-designentity-frameworkobject-oriented-design

I have inherited an ASP.NET website application and the previous developer has used what I believe are some DDD concepts. I am new to DDD and I have to admit I am struggling with the practical side of it having come from an N-Tier Transaction Script background.

One of the problems with the site is that it is slow. There is no paging on huge grids and also the business logic layer pulls down way more data than is needed for 90% of operations 70% of which are reads to bind data to grids.

The general design is that the business logic layer has a Service class per aggregate root, with various "GetByX()", 'FindBestMatching()" and "Update()" type methods on it. These Service classes are the points from which trees of domain objects are created such as "Organisation" and "User."

Back in my comfortable transaction script days, my service layer was similar: there would be some logic possibly, a call into a repository (or since EF 6 direct use of EF as it can be mocked for testing) and then the call would return. The objects that were returned would be DTO type objects containing return data relevant, including possibly some POCO entity objects. These DTOs would travel to clients via webservices, be bound to ASP.NET or Silverlight grids…all was good.

My operations on my service layer could be very specific, allowing for queries like:

"GetUsersWithSurnameIncludeChildren(string surname, int skip, int take)"

allowing for nice narrow DB queries that supported paging and eager loading of related data. It was fast and loaded only the data that was actually needed.

Now with this site I have inherited there is an actual OO model of the business domain. These classes are POCOs, not generated from EF, but EF is used database first as a repository (there is a lot of mapping between the domain objects and the EF objects). An example domain object is below (without any logic).

public class Organisation
{
    public int OrganisationID { get; set; }
    public string Name { get; set; }

    public IList<Organisation> AssociatedOrganisations { get; set; }
    public IList<User> Staff { get; set; }
    public IList<User> Managers { get; set; }

    // Business logic method implemented below here
}

Many of the classes are essentially copies of the underlying entity framework objects, others have a significant amount of logic encapsulated within them.

The way the site works currently is that every time the OrganisationService service class creates a new Organisation domain object (and it may create a collection in one hit) it also populates ALL of the fields and collections in that object…and all of the fields and collections in those objects! A huge deep tree is created in memory and a stack of joins and unions (generated by EF) is needed to get all of the data. This is totally inappropriate for a website that mainly displays loads of flat grids.

My questions are:

1) Is an application that is 70% pulling data out of a DB for display and 30% business logic actually a bad candidate for DDD?

2) If DDD is appropriate how are scenarios like this generally designed? Should I implement a separate "Query Service" that is designed just to pull out loads of flat data for binding to pages and grids (these could just be the EF POCOS themselves) and reserve the Domain objects just for parts of the application where logic must actually be performed?

3) Should I only load data into my Domain Object reference types and collections when it is actually accessed (like EF lazy loading…)? Previous posts I have read have suggested lazy loading in a Domain Object is a code smell: DDD Lazy Loading Code Smell

I am about to buy a DDD book tonight 🙂

Best Answer

After you read Evans' book, you will see that DDD is a collection of concepts. The book was written over a decade ago. My opinion of it today is that it has good parts but is easily misunderstood and sometimes used inappropriately. In reality, some parts you may not need or may not be right for your application or chosen tools.

As far as EF, I don't think that the DDD concept of combining data and behavior in your entities melds well with it. EF entity models should be devoid of behavior if you want to avoid a lot of unexpected errors and performance bottlenecks. As other answers here point out, using a CQ(R)S pattern is a good way of implementing behavior externally from EF entities. Bottom line is, try to avoid implementing a "rich domain model" using methods on EF entities. You can still crunch the business knowledge into "the model", but your "model" should contain different classes for data (entities) and behavior (operations).

I also don't like the idea of repositories, but that's primarily my opinion and I'm sure others will disagree when I say they really aren't necessary when you are using an ORM like EF. Maybe a decade ago, before we had modern generics, they were more useful. These days, you can wrap a single generic interface around an EF DbContext and have a single generic repository (along with unit of work).

On the other hand, things like the ubiquitous language, aggregate roots, bounded contexts, query criteria, etc. I consider to be pearls. Keeping the application layer thin is a timelessly good practice too. It sounds like the other developer might not have applied the appropriate DDD concepts, and as someone else here already said, created more problems than they solved.