Can you suggest DDD best practices - domain-driven-design

Probably similar questions have been asked many times but I think that every response helps to make the understanding of DDD better and better. I would like to describe how I perceive certain aspects of DDD. I have some basic uncertainties around it and would appreciate if someone could give a solid and practical anwser. Please note, these questions assume a 'classic' approach to DDD. This means using ORM's etc. Approaches like CQRS and event sourcing are not considered here.
Aggregates and entities are the primary objects that implement domain logic. They have state and identity. In this context, I perceive domain logic as the set of all commands that mutate that state. Does that make sense? Why is domain logic related exclusively to state? Is it legal to model domain objects that have no identitiy or no state? Why can't a domain object be implemented as a transaction script? Example: Consider an object that recommends you a partner for a dating site. That object has no real state, but it does quite a lot of domain logic? Putting that into the service layer implies that the domain model cannot cover all logic.
Access to other domain objects. Can aggregates have access to a repository? Example: When a (stateful) domain object needs to have access to all 'users' of the system to perform its work, it would need access them via the repository. As a consequence, an ORM would need to inject the repository when loading the object (which might be technically more challenging). If objects can't have access to repositories, where would you put the domain logic for this example? In the service layer? Isn't the service layer supposed to have no logic?
Aggregates and entities should not talk to the outside world, they are only concerned about their bounded context. We should not inject external dependencies (like IPaymentGateway or IEmailService) into a domain object, this would cause the domain to handle exceptions that come from outside. Solution: an event based approach. How do you send events then? You still need to inject the correct 'listeners' every time you instantiate a domain object. ORM's are about restoring 'data' but are not primarly intended to inject dependencies. Do we need an DI-ORM mix?
Domain objects and DTO's. When you query an aggregate root for its state does it return a projection of its state (DTO) or the domain objects themselves? In most models that I see, clients have full access to the domain data model, introducing a deep coupling to the actual structure of the domain. I perceive the 'object graph' behind an aggregate to be its own buisness. That's encapsulation, right? So for me an aggregate root should return only DTO's. DTO's are often defined in the service layer but my approach is to model it in the domain itself. The service layer might still add another level of abstraction, but that's a different choice. Is that a good advice?
Repositories handle all CRUD operations at the aggregate root level. What about other queries? Queries return DTO's and not domain objects. For that to work, the repsitory must be aware of the data structure of the domain which introduces a coupling. My advice is similar to before: Use events to populate views. Thus, the internal structure is not made public, only the events carry the necessary data to build up the view.
Unit of work. A controller at the system boundary will instantiate commands and pass them to a service layer which in turn loads the appropriate aggregates and forwards the commands. The controller might use multiple commands and pass them to multiple services. This is all controlled by the unit of work pattern. This means, repositories, entities, services - all participate in the same transaction. Do you agree?
Buisness logic is not domain logic. From a buisness perspective the realization of a use case might involve many steps: Registering a customer, sending an email, create a storage account, etc. This overall process can impossibly fit in a domain aggregate root. The domain object would need to have access to all kind of infrastructure. Solution: Workflows or sagas (or transaction script). Is that a good advice?
Thank you

The first best practice I can suggest is to read the Evans' book. Twice.
Too many "DDD projects" fail because developers pretend that DDD is simply OOP done right.
Then, you should really understand that DDD is for applications that have to handle very complex business rules correctly. In a nutshell: if you don't need to pay a domain expert to understand the business, you don't need DDD. The core concept of DDD, indeed, is the ubiquitous language that both the coders, the experts and the users share to understand each other.
Furthermore, you should read and understand what aggregates are (consistency boundaries) by reading Effective Aggregate Design by Vernon.
Finally, you might find useful the modeling patterns documented here.

Despite my comment above, I took a stab at your points. (note: I'm not Eric Evans or Jimmy Nilsson so take my "advice" with a grain of salt).
Your example "Consider an object that recommends you a partner for a dating site.", belongs in a Domain service (not an infrastructure service). See this article here - http://lostechies.com/jimmybogard/2008/08/21/services-in-domain-driven-design/
Aggregates do not access repositories directly, but they can create a unit of work which combines operations from multiple domain objects into one.
Not sure on this one. This should really be a question by itself.
That's debatable, in theory, the domain entities would not be directly available outside the aggregate root, but that is not always practical. I consider this decision on a case-by-case basis.
I not sure what you mean exactly by "queries". If modeling all possible "reading" scenarios in your domain does not seem practical or provide sufficient performance, it suggests a CQRS solution is probably best.
Yes, I agree. UOW is a tool in your toolbox that you can use in various layers.
This statement is fundamentally wrong "Business logic is not domain logic". The domain IS the representation business logic, thus one reason for using ubiquitous language.

Related

Should a Domain Entity call a repository?

I’m designing a shipping application and trying to use Clean Architecture and DDD. Deep in the core of the domain layer we have many configurable business rules. For example, there are business rules for determining the optimal carrier of a shipment, determining shipping mode, determining the payment type, etc. Each business rule selects data from the database so I plan on using a BizRule Repository. The problem is that according to my understanding of DDD principles, Domain Entities (e.g. Shipment) should not call repositories(e.g. BizRuleRepository). The Use Case layer should be the one that calls repositories. If I take this approach then I will have to move many complex business rules to the Use Case layer and I'm not sure if that is the best approach. In this case, does it make sense to make an exception and have the domain entity call a repository? Thank you in advance.
Should a Domain Entity call a repository?
Generally speaking, no; it doesn't make sense for an entity (which is a domain concern) to be communicating directly with a repository (which is plumbing).
Evans, when organizing his book, assigned these ideas to different chapters
A Model Expressed in Software -- describes Entities
The Life Cycle of a Domain Object -- describes Repositories
It's a problem of language; Repositories normally have collection or persistence semantics, which are not (typically) part of the ubiquitous language of the domain.
That said, there is a loop hole; domain services can describe data retrieval using the ubiquitous language, and delegate that work to application or infrastructure services.
So (assuming for the moment that the business rules are a domain concept), you would have a domain entity that knows which business rule it needs, and a domain service that knows how to retrieve a business rule, and then the entity that knows how to use it.
If business rules are not a domain concept, then some of the work shifts from the entity into the domain service, but the core of the pattern remains the same -- the entity passes arguments to the service, the service returns a domain value the entity understands, the entity decides how to apply that value in its current processing.
We can solve any problem by introducing an extra level of indirection
It's a bit of a shell game; under the covers, we're still using the plumbing; but the domain model only sees the porcelain.
That extra layer of indirection can be really handy when you want to unit test the domain logic without dragging in the entire world of plumbing dependencies: you replace the domain service with a test double.
If it is just for readings it should be ok, maybe it can be cleaner having an interface/service (also with just 1 method) that express the desired query to your store, decoupling your entity from the repository.
In this way you can easily mock the query during tests, and in the future the lookup method can be easily improved in its own class (or you can also pass different strategies/implementation for the lookup).
Problem arises when you use repositories to write inside entities.

DDD & Factories - Intensive CRUD Operations

We have recently decided to adopt DDD in my team for our new projects because of the so many obvious benefits (coming from the Active-Record pattern school) and there are a couple of things that are yet unclear.
Say I have an entity Transaction that depends on the following entities (that each in turn depends on other so many entities):
1. Customer
2. Account
3. Currency
When I make use of factories to instantiate a Transaction entity to pass to a Domain Service for some fancy business rules, do I make so many queries to setup all these dependent instances?
If I have overloads in my factory that skip such dependencies then those will be null in some cases and it will become too complicated to differentiate when I can access those properties and when I cannot. With Active-Record pattern I just use lazy loading and have them load only on demand. Any ideas with DDD?
EDIT:
In my scenario “Transaction” seems to be the best candidate for an Aggregate root. I have defined a method in my Application Service “InitiateTransaction” (also have a “FinalizeTransaction” as it involves a redirect to PayPal) and takes as parameters the DTOs needed to carry AccountId, CurrencyId, LanguageId and various other foreign keys as well as Transaction attributes.
When calling my Domain Services (Transaction Processor and Fraud Rule Evaluator), I need to specify the “Transaction” Aggregate with all dependencies loaded (“Transaction.Customer”, “Transaction.Currency”, etc.).
So if I am correct the steps required are:
1. Call some repository(ies) to retrieve Customer, Currency etc.
2. Call TransactionFactory with dependencies specified above to get a Transaction object
3. Call Domain Services with fully loaded Transaction object for business rules to take place
Correct? Additionally, my concern was about steps 1 and 2.
If “Customer”, “Currency” and other Entities/Value Objects “Transaction” depends on, have in turn other dependencies. Do I try to set up those as well? Because it seems to me that if I do I will end up with very bloated code in my Application Service and not very reusable to place in a separate method. However, if I don’t and just retrieve those from a repository with a “GetById(id)”as you suggested, my code could end up buggy as say I need property “Transaction.Customer.CreatedByUser” which returns a “User” instance, it will be null because repositories only load flat instances.
EDIT:
I ended up using GetById(id) to load only the dependencies I knew they were needed in my Services. Not a big fun of accidentally accessing null instances due to flat loading but I have my unit tests to protect me from taking it to production!!
I highly doubt it that Currency is an entity, however it's important to model things like how they defined and use by the real Domain. Forget factories or other implementation details like the db, you need to make sure you have defined the concepts right.
Once you've done that, you'd already identified the aggregate root as well. Btw, the entities should encapsulate the relevant business rules. Use Services to implement use-cases i.e to manage the interaction between the domain objects and other parts such as the repository.
You should keep EVERYTHING related to db and CRUD in the repository, and have the repo work only with the aggregate roots. Also, for querying purposes, you should use CQRS so that all the queries would be done on a read model. For Domain purposes, a Get(id) is 99% enough and that method returns an aggregate root.
Be aware that DDD is very tricky, the most difficult part is modeling the Domain correctly, all the buzzwords are useless if the model is wrong.

DDD: how to organize builders that bootstrap domain objects? Same Bounded Context?

I'm restructuring my current project to be better in-line with DDD best practices.
As part of this setup an admin-task allows certain domain-objects / aggregates to be (re)-bootstrapped based on a config file/algo combo. I have a good use-case for this that does require it to be part of a live system as opposed only to testing (text fixtures) for example.
I'm struggling how to best model refactor this in a DDD context:
Basically: would the builders/bootstrappers be infrastructure services belonging to the same Bounded Context as the Domain Objects? Would this feel natural? The flow I see is that an admin gets access to these functions using a special Admin Application Service which in turn calls the builders to do their work.
On the other hand, this admin functionality feels like a separate part of the system so perhaps I shouldn't pollute the domain objects (or their factories) with methods to support the bootstrapping. IOW: this could mean a seperate Bounded Context, with a completely different (logic-less) domain model purely used for persisting to a DB. That however doesn't feel very DRY to me, as I might end up defining models twice (once in each BC)
What would be the best way to go about this?

Where to put business logic in DDD

I'm trying to figure out the best way to build an easily maintainable and testable architecture. Having gone through several projects, I've seen some pretty bad architectures and I want to avoid making future mistakes on my own projects.
Let's say I'm building a fairly complex three layer application and I want to use DDD. My question is, where should I place my business logic? Some people say it should be placed in services (service layer) and that does make sense. Having a number of services which adhere to Single Responsibility Principle makes sense.
However, some people said that this is an anti pattern and that business logic shouldn't be implemented in the service layer. Why is this?
Let's say we have IAuthenticationService which has a method with bool UsernameAvailable(string username) signature. The method would implement all required logic to check whether the username is available or not.
What is the problem here according to the "this is an antipattern" crowd?
If you put all your business logic in an (implicitly stateless) service layer you're writing procedural code. By decoupling behavior from data, you're giving up on writing object-oriented code.
That's not always bad: it's simple, and if you have simple business logic there's no reason to invest in a full-fledged object-oriented domain model.
The more complex the business logic (and the larger the domain), the faster procedural code turns into spaghetti code: procedures start calling each other with different pre- and post-conditions (in incompatible order) and they begin to require ever-growing state objects.
Martin Fowler's article on Anemic Domain Models is probably the best starting point for understanding why (and under what conditions) people object to putting business logic in a service layer.
A service layer in itself is not an anti-pattern, it is a very reasonable place to put certain elements of your business logic. However, you do need to apply discretion to the design of the service layer, ensuring that you aren't stealing business logic from your domain model and the objects that comprise it.
By doing that you can end up with a true anti-pattern, an anaemic domain model.
This is discussed in-depth by Martin Fowler here.
Your example of an IAuthenticationService isn't perhaps the best for discussing the problem - much of the logic around authentication can be seen as living in a service and not really associated with domain objects. A better example might be if you had some sort of IUserValidationService to validate a user, or even worse a service that does something like process orders - the validation service is stripping logic out of the user object and the order processing service is taking logic away from your order objects, and possibly also from objects representing customers, delivery notices etc...
You have to have 4 layers with DDD: Presentation, Application, Domain, and Infrastructure.
The Presentation layer presents information to the user, interprets user commands.
All dependent on use-cases logic (application entities, application workflow components, e.g. DTOs, Application services) goes to the Application layer (Application logic). This layer doesn’t contain any business logic, does not hold the state of business objects, can keep the state of an application task’s progress.
All invariant to use-cases logic (business entities, business workflow components, e.g. Domain model, Domain services) goes to the Domain layer (Domain logic). This layer is responsible for concepts of the business domain and business rules.
The Infrastructure layer may have IoC, Cache, Repositories, ORM, Cryptography, Logging, Search engine, etc.

Questions regarding Domain driven Design

After reading Eric Evans' Domain driven Design I have a few questions. I searched but no where i could able to find satisfying answers. Please let me know if anyone of you have clear understanding below questions.
My concerns are
Repository is for getting already existing aggregates from DB,Web service .
If yes, Can Repository also have transaction calls on this entity (i.e Transfer amount,send account details ...etc)
Can Entity have Methods which have business logic in which it calls infrastructure Layer services for sending emails .. logs etc (Entity methods calling IS services direclty).
Repository implementation and Factory classes will reside in Infrastrucure Layer. is that correct statement ?
Can UI layer (controller) call Repositry methods directly ? or should we call these from Application layer ?
There are still lot many confusion in my mind ... please guide me ...
Books i am using Eric Evan's domain driven desing ......
.NET Domain-Driven Design with C#
There is a lot of debate about whether Repositories should be read-only or allow transactions. DDD doesn't dictate any of these views. You can do both. Proponents of read-only Repositories prefer Unit of Work for all CUD operations.
Most people (self included) consider it good practice that Entities are Persistent-Ignorant. Extending that principle a bit would indicate that they should be self-contained and free of all infrastructure layer services - even in abstract form. So I would say that calls to infrastructure services belong in Service classes that operate on Entities.
It sounds correct that Repository implementations and Factories (if any) should reside in the infrastructure layer. Their interfaces, however, must reside in the Domain Layer so that the domain services can interact with them without having dependencies on the infrastructure layer.
DDD doesn't really dictate whether you can skip layers or not. Late in the book, Evans talks a bit about layering and calls it Relaxed Layering when you allow this, so I guess he just sees it as one option among several. Personally I'd prefer to prevent layer skipping, because it makes it easier to inject some behavior at a future time if calls already go through the correct layers.
Personally, in my latest DDD-project, I use a Unit Of Work that holds an NHibernate session. The UoW is ctor injected in the repositories, giving them the single responsible of Add, Remove and Find.
Evans has stated that one piece of the puzzle that's missing in the DDD book is «Domain Events». Using something like Udi Dahan's DomainEvents will give you a totally decoupled architecture (the domain object simply raises an event). Personally, I use a modified version of Domain Events and StructureMap for the wiring. It works great for my needs.
I recommend, based on other recommendations, that the Repository interfaces be a part of the model, and their implementations be a part of the infrastructure.
Yes! I've personally worked on three DDD web projects where services and repositories were injected to the presenters/controllers (ASP.NET/ASP.NET MVC) and it made a lot of sense in our context.
The repository should only be for locating and saving entities, there should not be any business logic in that layer. For example:
repository.TransferAmount(amount, toAccount); // this is bad
Entities can do things like send emails as long as they depend on abstractions defined in your domain. The implementation should be in your infrastructure layer.
Yes, you put your repository implementation in your infrastructure layer.
Can UI layer (controller) call Repositry methods directly ? or should we call these from Application layer ?
Yes, I try to follow this pattern for the most part:
[UnitOfWork]
public ActionResult MyControllerAction(int id)
{
var entity = repository.FindById(id);
entity.DoSomeBusinessLogic();
repository.Update(entity);
}

Resources