Search code examples
c#.netdomain-driven-designddd-repositoriesddd-service

DDD design understanding


I've been starting to learn about DDD and I have couple of questions so that I can improve my understanding of it.

So a typical DDD architecture looks like this

Domain Layer => this layer should be technology agnostic and should contain the following

Domain.Entities (different from the persistence layer Entities, should contain only validation rules ? any other domain business should go here?)

Domain.ValueObjects (objects that do not require to be unique in the domain, should contain only validation rules)

Domain.Services (this layer should contain business logic that although related to an Aggregate, does not fit into the Aggregate itself. orchestrators for operations that require multi Domain.Entities and/or Domain.ValueObjects collaborating together)

Domain.Factories ( this layer is somehow not fully understood, i mean it's responsibility is to create Aggregates or what ?) Is it purely the Factory Design Pattern or is different from it?

Domain.Repositories (this layer is also ambiguous, except for the fact that i know that this layer is responsible to communicate with external services, what type of business logic should it handle?)

Anti-corruption layer (this layer should act as a gateway between the Domain layer and the Application Layer, it should be responsible with Translation of responses and requests from one layer to the other)

Application Layer => should only be used to expose data in a format easy to understand by the Client. Filtering is done in this layer (Linq-To-SQL) / (Linq-To-Entity)

Client (final layer) => should be free of any logic only exposes the models that the Application Layer Services provides.

other Layers as I see them

Shared.Kernel (Domain.ValueObjects / Domain.Entites (not AggregateRoots) that are shared across multiple Bounded Contexts)

Infrastructure.Domain.Common(shared across the entire Domain, ex AggregateRoot, BaseEntity, BaseValueObject etc)

Infrastructure.DataAccess.Provider(example EntityFramework / nHibernate/ MongoDriver , with whom this layer should communicate ? the Application Layer ?


Solution

  • The place to start with DDD is "the blue book": Domain Driven Design by Eric Evans

    a typical DDD architecture looks like

    a layered architecture. Evans recaps four conceptual layers

    • User Interface
    • Application
    • Domain
    • Infrastructure

    In Chapter 4 (Isolating the Domain), Evans points out

    The part of the software that specifically solves problems from the domain usually constitutes only a small portion of the entire software system, although its importance is disproportionate to its size. To apply our best thinking, we need to be able to look at the elements of our model and see them as a system.... We need to decouple the domain objects from other functions of the system, so we can avoid confusing the domain concepts with other concepts related only to software technology or losing sight of the domain altogether....

    Within the "domain layer", Evans recognizes two different sets of concerns.

    Domain entities, value objects, and domain services model the business in the software (Chapter 5). In other words, these elements the model the concepts that your domain experts would recognize.

    Repositories and Factories are life cycle concerns - not strictly related to the business as the experts would recognize it, but instead acting as the boundary between the application layer and the domain layer.

    In Evan's formulation, the validation of business rules typically lives in the domain entities (not domain services). As is common in OO styles, the domain entities combine state (domain values) and behavior (rules for change) -- any change to a persistence layer entity (you are right, not the same thing) happens because of code executed by a domain entity.

    Anti corruption layers more about integrating with an external data source (perhaps a legacy system) then they are about integrating with the application layer.

    Implement a façade or adapter layer between a modern application and a legacy system that it depends on. This layer translates requests between the modern application and the legacy system. Use this pattern to ensure that an application's design is not limited by dependencies on legacy systems.

    You might want to review the DDD Sample application available on github. It's a decent sketch of how the different pieces might fit together.

    Note: these days, the layered architecture has lost ground to some of the other alternatives, and we are beginning to see more work on implementing the domain model with a functional core (rather than the OO style).