애플리케이션 서비스는 사용자의 유스케이스를 구현하는 객체라고 할 수 있다.
아래와 같은 User 와 UserService 가 있다.
class User {
private id;
private name;
}
class UserService {
public isExists(User user) { ... }
}
User 는 사용자 도메인 모델을 투영시킨 엔티티이며 UserService 는 User 도메인이 처리하기 부자연스러운 책임을 수행하는 도메인 서비스이다.
여기서 '유저 등록' 이라는 클라이언트의 요구사항을 수행해야 된다면 어느 객체에 책임을 부여해야 할까?
만약 Client 라는 객체에게 그 책임을 부여한다고 가정하자.
class Client {
private UserService userService;
register() {
// 상세 구현 내용
}
}
처음에는 유저 등록에 대한 책임만 가지겠지만 지속해서 클라이언트의 요구사항이 늘어날 수록 Client 객체의 책임 또한 증가한다.
class Client {
private UserService userService;
private ProductService productService;
private CategoryService categoryService;
register() {
// 상세 구현 내용
}
addCategory() {
// 상세 구현 내용
}
removeProduct() {
// 상세 구현 내용
}
}
이는 Client 객체의 높은 결합도와 낮은 응집성으로 이어진다.
이를 해결하기 위해 존재하는 것이 애플리케이션 서비스이다.
애플리케이션 서비스는 특정 도메인 및 도메인 서비스에 대한 클라이언트의 유즈케이스 해결의 책임을 갖는 객체이다.
class Client {
private UserApplicationService userApplicationService;
private ProductApplicationService productApplicationService;
private CategoryApplicationService categoryApplicationService;
register() {
return userApplicationService.register();
}
addCategory() {
return productApplicationService.addCategory();
}
removeProduct() {
return categoryApplicationService.removeProduct();
}
}
이처럼 애플리케이션 서비스를 사용하면, Client 는 상세한 구현이 아닌 각 애플리케이션 서비스의 퍼블릭 인터페이스에만 의존하게 할 수 있다.