Application Services | Application Service Layer | Domain Driven Design
Application Services
- Application services and a service layer allow you to isolate technical concerns from domain logic.
- Technical concerns include transactions, database connections, and e-mails.
- Application services are responsible for coordinating with the domain to carry out full business use cases.
- When communicating with the domain, application services should invoke expressive high-level APIs on domain objects.
- An important responsibility of application services is to protect domain structure by presenting higher layers and external components with more stable interfaces to couple themselves to.
- You can use design patterns like the command processor pattern and asynchronous patterns in the service layer.
- Testing application services is an opportunity to express high-level behaviors or full business use cases, in the ubiquitous language, while covering a high percentage of the implementation.
How do you implement the Application Layer?
I’m by no means an expert in this area of application development, but it seems to me that there are basically two methods for implementing the Application layer.
Application Services
The first method is to use Application Services. An Application Service is basically just a class with methods for the various tasks your application can perform.
For example, you might have the following
IdentityApplicationService
:class IdentityApplicationService
{
/**
* Register a new user
*
* @param string $email
* @param string $username
* @param string $password
* @return User
*/
public function register($email, $username, $password)
{
// register a new user
}
}
The
register()
method on this Application Service would accept the raw strings from the request and use the internal RegisterUserService
to create a new User
object.
The Application Service would be injected with the various services it requires to complete the task. Application Service would generally separated by functional area of the application and would group together related methods.
Command Bus
Alternatively you have the Command Bus approach. A Command Bus accepts a Command object and delegates it to a Command Handler.
For example, you might have a
RegisterUserCommand
that is sent to the Command Bus and delegated to a RegisterUserHandler
.
The
RegisterUserHandler
would be able to handle the process for registering a new user in the application.What are the differences between Application Services and The Command Bus?
There are many differences between Application Services and The Command Bus and both have their positives and negatives.
Firstly, Application Services tend to be more complicated than using a Command Bus. This is because grouping together many related tasks means you end up with a large class that requires a number of dependencies and has a lot of responsibility.
Using a Command Bus is far more simpler because each Command has a single Command Handler. Each Handler only needs to be concerned with satisfying a single Command, and so your code ends up much closer to The Single Responsibility Principle.
However on the other hand, using a Command Bus can be more complicated than using an Application Service in some situations. A Command Bus should not return a value after a Command has been handled.
For example, if you were creating a new resource in your application, you would not be returned the id of the new resource so you could redirect the user to it’s view page.
Now arguably, this is probably only going to make using a Command Bus more difficult if you are trying to use a Command Bus for the wrong job. If you face this situation, you should probably use an Application Service.
However testing A Command Bus is more difficult because it’s harder to test code when there is no return value from the method call. I’m still trying to get my head around this one.
When you begin writing The Application Layer of your application, you don’t need to choose either Application Services or a Command Bus. You can very easily use one type of implementation for certain functionality of your application and another for other aspects. It’s about choosing the right tool for the job, and not trying to fit a square peg in a round hole.
Services
We can define services as processes that perform certain tasks. Employees and evolved from Service Oriented Architecture or Remote Procedure Call . Generic tasks or actions that are not associated with a single determined single object instance, so the most common tendency is to create static methods on the entity or aggregate . This practice is not considered optimal because it does not follow the principles of development and greatly complicates testing, and it is considered bad practice to access repositories within the aggregates or entitiesin the domain model. The need to include static methods in the domain model is a good indicator to create a service .
Application Services
- Direct client of Domain Services and domain model.
- Use cases of the application that coordinates and orchestrates the requests to the business logic and repositories.
- Coordinates the responsibilities of the domain model and domain services.
- Hosted in Application Layer .
Domain Services
- Contains the logic / business rules .
- Transform one domain object to another.
- Calculate the value by entering objects from the domain model.
- They can access repositories.
- Hosted in Domain Layer .
In order to follow the development principles , we will declare interfaces for each Service.
The services are not a silver bullet , if we use them in excess extracting all the logic of application or domain in services, we can cause an Anemic Domain Model . It must be determined and correctly decided if an entity / aggregate method should be included in the domain model or create a service following Single Responsibility Principle at all times .
The services are not a silver bullet , if we use them in excess extracting all the logic of application or domain in services, we can cause an Anemic Domain Model . It must be determined and correctly decided if an entity / aggregate method should be included in the domain model or create a service following Single Responsibility Principle at all times .
In general, the implementations of the services are hosted in the infrastructure layer , although sometimes when we have a single implementation they can be hosted in the same layer where the interface is declared.
No comments:
Post a Comment