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.*
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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With