What is a Service on a Code Base (Domain Driven Approach)
Definition, characteristics, types and accessing Services
On almost every enterprise code base application we use services to add and maintain business or other types of functionalities.
But what is a Service 🤔❓❔
How we are sure that we have designed and implemented well-defined and well-structured services 🤔❓❔
🌊Let’s dive into the main aspects of a Service
✒️ Definition
A Service is an operation that can’t fit natural in a domain model without encapsulating state
In simple words, a Service supports and extends the functions of a domain model without an internal state and with a well-defined responsibility.
For example, we have a domain model called User
The User Domain Model has to send some notifications every time a User is created or updated.
We can easily figure out that these notifications can’t fit naturally on the UserDomainModel class.
This is where a service can be fit, we create a NotifyUserService Class to extend the UserDomainModel with notification functionalities.
NotifyUserService does not need any state to encapsulate and has a clear responsibility: to send all the notifications that UserDomainModel needs.
✏️ Characteristics
Services are not buckets of code that help us to implement new or maintain old functionalities.
Services are not the only place tha can host functionalities
Services must have clear characteristics to provide value and contribute to a more clean code base design :
Can’t fit naturally on a domain model, as described before Services are extending and supporting Domain Model Classes
Well-defined responsibility, every service must have a clear and well-defined context that is responsible
Well-defined interface, clients should use the service with ease and it should be reusable
Stateless, any client can use any instance of a particular Service without the need to configure the inner state of the Service
🦖 Types
Services on a Layer Based Architecture App can fall into 3 types
Application
Services that support the application needs, lifecycle, and life.
Examples HttpRequestExtractService, AuthMiddlewareService, InvokeHttpControllerService, RouterService etc.
Domain
Services that implement all the business requirements
Infrastructure
Services that aren’t on the above 2 types.
Examples Emailer, DatabaseCommunications, EventDispatcer, EventConsumers HttpRequestClient, IOReaderWriter, etc
🍃 Accessing Services
Creating and fetching Services must be easy and straightforward for all client Classes.
All mature enterprise frameworks such as Spring Boot, NestJS, Laravel, Symfony, and many more have sophisticated mechanisms like Service Container to fetch and manipulate easily Services.
In case our app doesn’t have a Service Container we can wrap a Service with a Singleton pattern and use the Factory pattern to act as a producer for all client Classes.
References
Domain-Driven Design: Tackling Complexity in the Heart of Software