Application service
Coordinates use cases, transactions, repositories, gateways, and side effects.
This distinction is often blurred in Java systems. Application services usually coordinate use cases, transactions, repositories, gateways, and side effects. Domain services express business logic that does not belong naturally to one entity or value object. Confusing the two usually makes the model either procedural or unclear.
If shipment promise logic ends up in controllers or application services forever, the domain stays weak. But if orchestration and infrastructure suddenly get forced into domain services, the domain becomes noisy and impure. The boundary matters.
Application services answer: what should the system do for this use case? Domain services answer: what does the business rule mean when no one object owns it naturally? One is about coordination. The other is about domain logic.
Most confusion disappears when you ask whether the method is mostly orchestrating collaborators or mostly expressing business meaning.
Coordinates use cases, transactions, repositories, gateways, and side effects.
Expresses business rules that do not fit naturally inside one domain object.
If the distinction blurs, the domain model usually weakens or the service layer becomes muddy.
| Question | Application service | Domain service |
|---|---|---|
| Main role | Use-case coordination | Business meaning across domain concepts |
| Infrastructure access | Common | Should be limited or absent |
| Language | Use-case oriented | Domain-policy oriented |
package org.javaomnibus.ecommerce.application;
public final class ShipOrderApplicationService {
private final OrderRepository orderRepository;
private final ShipmentPort shipmentPort;
private final ShipmentPromiseService shipmentPromiseService;
public void ship(OrderId orderId) {
Order order = orderRepository.requireById(orderId);
ShipmentPromise promise = shipmentPromiseService.calculate(order, InventorySnapshot.current());
shipmentPort.schedule(order.id(), promise);
orderRepository.save(order);
}
}