In DDD, should business logic not be completely contained in domain types?
Yes. And, in DDD, Services are actually domain objects.
In DDD, Services are not a layer but rather a type of business object.
What are these domain services really and how can we identify them?
The way to identify them is in your quote, but I would write differently:
In DDD, Services are objects that contain business logic that does not belong naturally to any Entity.
The difference between my affirmation and your quote is that I took the comma and the "but". There is no "but / yet / however /" in the Services definition. They simply are what they are. I also took the "business logic that does not belong to Value Objects" because Value Object never has a business rule.
How to choose where a business logic should reside
View a business rule and identify which business it belongs to. The question to ask is: "Which entity should have this behavior?" If you can not determine and the design is ok then this business rule belongs to a Service and not to an Entity.
Eventually a business rule appears to belong to an Entity, but it will affect many entities of that type and not just a single instance - in this case business logic also belongs to a service.
Entity Behaviors
See this business rule:
- Download an incoming payment account that was paid today.
If you have a AccountReceive entity, this business logic belongs to this entity. You get the Intent of this entity and invokes your LowQuestion behavior:
ContaReceber contaReceber = contaReceberRepo.get(contaId);
contaReceber.baixaPorQuitacao(dataReferencia);
contaReceberRepo.persist(contaReceber);
Service Behaviors
See this other business rule:
- Purge uncollectible accounts receivable.
An incoming account has no way of knowing that it is uncollectible. To know which accounts are uncollectible, you need to get the parameters from somewhere. These parameters will be, for example: accounts that have been delayed for more than five years without interest on the part of the client. The knowledge contained in several other entities is required to find out which accounts payable meet this criterion.
This business rule of course does not belong to any Entity, so it belongs to a service, which would be, for example:
ServicoBaixaAutomatica servicoBaixaAutomatica = BaixaAutomaticaService.get();
servicoBaixaAutomatica.expurgarIncobraveis(dataReferencia)
Complementing
Business or domain objects, in DDD, do not constitute layers; on the contrary, they all reside on the same layer, the business layer (of course), usually called domain .
The layers in DDD are:
-
Interfaces: is the interface of the system with the outside world. It could be for example a graphical user interface or a service frontend.
-
Application: contains the mechanics of the application, directs business objects to user interactions or other systems.
-
Domain: layer where business objects reside (Entities, Value Objects, Aggregations, Services, Factories, Repositories).
-
Infrastructure: supports the other layers, offering for example mapping between business and database objects and access services to these databases.