Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD domain services: what should a service class contain?

In Domain Driven Design, domain services should contain operations that do not naturally belong inside an entity.

I've had the habit to create one service per entity and group some methods inside it (Organization entity and OrganizationService service).

But the more I think about it: OrganizationService doesn't mean anything, "Organization" is not a service, it's a thing.

So right now I have to add a Organization deep copy functionality that will duplicate a whole Organization aggregate, so I want to put it in a service.

Should I do: OrganizationService::copyOrganization(o)?

Or should I do: OrganizationCopyService::copyOrganization(o)?

More generally: is a "service" an abstract concept containing several operations, or is a service a concrete operation?

Edit: more examples given the first one wasn't that good:

  • StrategyService::apply()/cancel() or StrategyApplicationService::apply()/cancel()? ("Application" here is not related to the application layer ;)
  • CarService::wash() or CarWashingService::wash()?

In all these examples the most specific service name seems the most appropriate. After all, in real life, "car washing service" is something that makes sense. But I may end up with a lot of services...

*Note: this is not a question about opinions! This is a precise, answerable question about the Domain Driven Design methodology. I'm always weary of close votes when asking "should I", but there is a DDD way of doing things.*

like image 453
Matthieu Napoli Avatar asked Jul 19 '13 12:07

Matthieu Napoli


People also ask

What are domain services in DDD?

Introduction. Domain Services (or just Services in DDD) is used to perform domain operations and business rules. In his DDD book, Eric Evans describes a good Service in three characteristics: The operation relates to a domain concept that is not a natural part of an Entity or Value Object.

What is the domain service?

Domain Services stores centralized directory information and lets users and domains communicate. When a user attempts to connect to a device or resource on a network, this service provides login authentication, verifying the user's login credentials and access permissions.

Is DDD good for microservices?

In addition, DDD approaches should be applied only if you are implementing complex microservices with significant business rules. Simpler responsibilities, like a CRUD service, can be managed with simpler approaches. Where to draw the boundaries is the key task when designing and defining a microservice.

What is DDD service layer?

In DDD, a Domain Service is a specific type of domain layer class that we use when we want to put some domain logic that relies on two or more entities.


2 Answers

I think it's good if a domain service has only one method. But I don't think it is a rule like you must not have more than one method on a domain service or something. If the interface abstracts only one thing or one behaviour, it's certainly easy to maitain but the granularity of the domain service totally depends on your bounded context. Sometimes we focus on low coupling too much and neglect high cohesive.

like image 187
Yugang Zhou Avatar answered Oct 30 '22 17:10

Yugang Zhou


This is a bit opinion based I wanted to add it as a comment but ran out space.

I believe that in this case it will make sense to group the methods into one a separate OrganizationFactory-service with different construction method.

   interface OrganizationFactory{
       Organization createOrganization();
       Organization createOrganizationCopy(Organization organization);
   }

I suppose it will be in accordance with information expert pattern and DRY principle - one class has all the information about specific object creation and I don't see any reason to repeat this logic in different places.

Nevertheless, an interesting thing is that in ddd definition of factory pattern

Shift the responsibility for creating instances of complex objects and AGGREGATES to a separate object, which may itself have no responsibility in the domain model but is still part of the domain design. Provide an interface that encapsulates all complex assembly and that does not require the client to reference the concrete classes of the objects being instantiated.

the word "object" is in a generic sense doesn't even have to be a separate class but can also be a factory method(I mean both the method of a class and the pattern factory method) - later Evans gives an example of the factory method of Brokerage Account that creates instances of Trade Order.

The book references to the family of GoF factory patterns and I do not think that there's a special DDD way of factory decomposition - the main points are that the object created is not half-baked and that the factory method should add as few dependecies as possible.

update DDD is not attached to any particular programming paradigm, while the question is about object-oriented decomposition, so again I don't think that DDD can provide any special recommendations on the number of methods per object.

Some folks use strange rules of thumb, but I believe that you can just go with High Cohesion principle and put methods with highly related responsibilities together. As this is a DDD question, so I suppose it's about domain services(i.e. not infrastructure services). I suppose that the services should be divided according to their responsibilities in the domain.

update 2 Anyway CarService can do CarService::wash()/ CarService::repaint() / CarService::diagnoseAirConditioningProblems() but it will be strange that CarWashingService will do CarWashingService::diagnoseAirConditioningProblems() it's like in Chomsky's generative grammar - some statements(sentences) in the language make sense, some don't. But if your sentence contains too much subjects(more than say 5-7) it also will be difficult to understand, even if it is valid sentence in language.

like image 31
Boris Treukhov Avatar answered Oct 30 '22 15:10

Boris Treukhov