I would like to know what differentiates a Service class from a utility class or a helper class? A class only with underlying methods calls the dao's is a service? Doesn't the usage of Helper classes violates SRP?
The lines can be a little blurry, but I see it this way:
A Service class/interface provides a way of a client to interact with some functionality in the application. This is typically public, with some business meaning. For example, a
TicketingServiceinterface might allow you to
sellTicketand so on.
A helper class tends to be hidden from the client and is used internally to provide some boiler plate work that has no business domain meaning. For example, let's say you wanted to convert a date into a timestamp in order to save it to your particular datastore. You might have a utility class called
convertDateToTimestampmethod that performs this processing.
Services are not simply tightly coupled to DAOs, it's a broader term/usage pattern than persistence
Helper classes do not violate SRP if coded in accordance with that principle. That is, each method should do one thing and one thing well, the class should perform one type of utility help, (e.g. Date conversion) and do that well.
For me, I go by the Eric Evans definition of
service which is something like this:
Generally, in a well designed system, most classes (in the Domain Model) have quite clear responsibility or function in that they deal with a specific entity or set of entities in the model.
- Account, Account Factory, Account Repository, etc
- Customer, Customer Factory, Customer Repository, etc
When you have functionality that does not belong with any particular entity it can be difficult to find a correct place for it to sit. I.e something that encapsulates a process that involves both an
Account AND a
So, that's where a
service comes in. It's where you put code that is in the Domain Model but does not naturally belong to one entity/component or another.
I think of a
helper as a kind of strategy class. To me its a place to put code that needs to be re-used by various classes but might not quite sit well as abstract methods inside the hierarchy of the classes who use it. Personally I find the term
helper a bit vague and don't really have them in my model. Although they exist in libraries that I use.
You mixed up two non related principals. Services and Helper-Classes are not connected. Especially the term "Service Class" is misleading - I think you are referring to a "Service" which is on a higher level of abstraction than classes. A service is characterized through
"a mechanism to enable access to one or more capabilities, where the access is provided using a prescribed interface and is exercised consistent with constraints and policies as specified by the service description."
This definition slightly changes depending on your context. However, the critical point is that the term "service" is on an abstract level, the level of architecture and domain knowledge. The "Helper Class" is a design pattern (even though it's a anti-pattern as they tend to evolve to blob's or god classes) referring to a class that encapsulate generic operations (notice that this is on a lower level of abstraction and is connected to the application/solution knowledge). I'm aware of the fact that there exists nearly no software not containing any kind of helper class, but still, it's bad practice.
One thing to be wary of is the multiple definitions of 'service' in DDD:
Application service: These sit in the application layer and communicate with the domain and data layer, they are the interface through which external systems/UI interact with the DDD system.
Domain Service: This can be used by the domain or the application layer, and contain business logic that does not fit neatly into one particular entity.
Infrastructure Service: These are used by the domain to communicate with external resources.
Helper classes tend to contain pieces of code or algorithms that would be reused by multiple entities, so can't really go into entities without violating the DRY principle. They are probably closest to Domain Services, in that they sort fulfil the same purpose (externalising business logic from entities) but they do it for different reasons.