Services
A service is a stateless object that implements domain, applicative or infrastructure logic.
Characteristics
Services can come in three flavors, depending upon the layer where they reside.
Domain services
A domain service contains pure domain logic that does not fit naturally on any existing domain object. Its name and the name of its operations should come from the ubiquitous language or be introduced into it if necessary. Parameters and return values should be domain objects or language types.
Application services
An application service contains coordination logic between other services. It is more tied to a specific use-case of the system from which it execute all the steps in a well-defined unit of work. Application services are often the ideal place to begin and end transactions.
Infrastructure services
An infrastructure service focuses on encapsulating a technical aspect of the application, like filesystem access, email, notifications, …
Statelessness
A service is always stateless. This does not mean that a service cannot change the global state of the application (that is, it may have side effects), but it should never hold a state of its own that could affect its behavior.
Declaration
To create a service with the business framework, create an interface annotated with @Service
:
@Service
public interface SomeService {
void someOperation();
}
Then create its implementation:
public class SomeServiceImpl implements SomeService {
@Override
public void someOperation() {
// do something
}
}
If you have more than one implementation of a service, you must differentiate them by applying a different qualifier on each implementation.
Usage
To use your service, inject its interface:
public class SomeClass {
@Inject
private SomeService someService;
public void someMethod() {
someService.someServiceOperation();
}
}
Example
Let’s consider a fund transfer service. It does not fit naturally into the Account
aggregate since it may have some complex
business logic that depends upon other services (currency exchange rate, transfer authorization between countries, …).
@Service
public interface FundsTransferService {
MoneyTransferReport transferMoney(
Account toBeDebited,
Account toBeCredited,
Amount transferAmount
);
}
Notice how the name of the service and its operation is meaningful from a business perspective. Avoid services with generic names such as «AccountManagementService» or worse «AccountService». Try instead to convey business meaning by using names from the ubiquitous language.