사용자와 상호작용은 표현 영역이 처리하기 때문에, 응용 서비스는 표현영역에 의존하지 않는다.
응용 영역은 사용자가 어떤 환경에서 요청하는지 알 필요가 없다. 단지 기능 실행에 필요한 입력 값을 받고 실행 결과만 리턴하면 된다.
1. 응용 서비스의 역할
응용 서비스는 사용자가 요청한 기능을 실행한다.
사용자의 요청을 처리하기 위해 리포지터리에서 도메인 객체를 가져와 사용한다.
응용 서비스는 주로 도메인 객체 간의 흐름을 제어하기 때문에 단순한 형태를 갖는다.
2. 응용 서비스의 구현
응용 서비스는 표현 영역과 도메인 영역을 연결하는 매개체 역할을 하는데 이는 디자인 패턴에서 퍼사드와 같은 역할을 한다.
응용 서비스의 크기
응용 서비스는 보통 다음의 두 가지 방법 중 한가지 방식으로 구현한다.
한 응용 서비스 클래스에 회원 도메인의 모든 기능 구현하기
각 기능에서 동일한 로직을 위한 코드 중복을 제거하기 쉽다는 장점이 있지만 한 서비스 클래스의 크기가 커지는 것이 단점이다.
코드 크기가 커지는 만큼 연관성이 없는 코드가 뒤섞여 코드를 이해하는데 방해가 된다. 이것은 코드를 점점 얽히게 만들어 코드 품질을 낮추는 결과를 초래한다.
구분되는 기능별로 응용 서비스 클래스를 따로 구현하기
한 응용 서비스 클래스에서 한 개 내지 2~3 개의 기능을 구현한다.
이 방식을 사용하면 클래스 개수는 많아지지만 한 클래스에 관련 기능을 모두 구현하는 것과 비교해서 코드 품질을 일정 수준으로 유지하는 데 도움이 된다.
또한 각 클래스별로 필요한 의존 객체만 포함하므로 다른 기능을 구현한 코드에 영향을 받지 않는다.
각 기능마다 동일한 로직을 구현할 경우 여러 클래스에 중복해서 동일한 코드를 구현할 가능성이 있다. 이 경우 별도 클래스에 로직을 구현해서 코드가 중복되는 것을 방지할 수 있다.
응용 서비스의 인터페이스와 클래스
인터페이스가 필요한 상황
구현 클래스가 여러개인 경우
하지만 응용 서비스는 런타임에 교체하는 경우가 거의 없고 한 응용 서비스의 구현 클래스가 두 개 이상인 경우도 드물다.
테스트 주도 개발을 하는 경우
표현 영역 부터 개발을 시작한다면 미리 응용 서비스를 구현할 수 없으니 인터페이스를 먼저 작성하게 된다.
표현 영역이 아닌 도메인 영역이나 응용 영역의 개발을 먼저 시작한다면 응용 서비스 클래스가 먼저 만들어진다. 이렇게 되면 표현 영역의 단위 테스트를 위해 응용 서비스의 Mock 객체가 필요한데 이를 위해 인터페이스를 추가할 수도 있다.
하지만 테스트 프레임워크의 도움을 받아 인터페이스가 없어도 표현영역을 테스트할 수 있다.
함수 파라미터와 값 리턴
응용 서비스에 데이터로 전달할 요청 파라미터가 두 개 이상 존재하면 별도 DTO 클래스를 사용하는것이 좋다.
응용 서비스에서 애그리거트 자체를 리턴하면 도메인의 로직 실행을 응용 서비스와 표현 영역 두 곳에서 할 수 있게 된다. 이것은 기능 실행의 로직을 응용 서비스와 표현 영역에 분산시켜 코드의 응집도를 낮추는 원인이 된다. 그러므로 가급적 응용 서비스는 표현 영역에서 필요한 데이터만 리턴하는 것이 기능 실행 로직의 응집도를 높이는 확실한 방법이다.
표현 영역에 의존하지 않기
응용 서비스의 파라미터 타입을 결정할 때 주의할 점은 표현 영역과 관련된 타입을 사용하면 안 된다.
표현 영역의 응집도가 낮아지고 각 계층의 결합도가 높아지는 원인이 되기 때문에 철저하게 분리하는것이 좋다.
트랜잭션 처리
일반적으로 트랜잭션 처리는 응용 서비스에서 담당한다.
3. 표현 영역
표현 영역의 책임은 크게 다음과 같다.
사용자가 시스템을 사용할 수 있는 흐름(화면)을 제공하고 제어한다.
사용자의 요청을 알맞은 응용 서비스에 전달하고 결과를 사용자에게 제공한다.
사용자의 세션을 관리한다.
4. 값 검증
값 검증은 표현 영역과 응용 서비스 두 곳에서 모두 수행할 수 있다.
원칙적으로는 모든 값에 대한 검증은 응용서비스에서 처리한다.
표현 영역에서 필수 값과 값의 형식을 검사하고 응용 서비스에서 논리적 오류를 검사해도된다.
5. 권한 검사
보통 다음 세 곳에서 권한 검사를 수행할 수 있다.
표현 영역
응용 서비스
도메인
각 영역 별로 필요한 권한 검사를 할 수 있다.
프레임워크가 제공하는 권한 검사 기능을 확장해서 적용할 수도 있다. 그런데 도메인 객체 수준의 권한 검사 로직은 도메인별로 다르므로 도메인에 맞게 보안 프레임워크를 확장 하려면 프레임워크에 대한 높은 이해도가 필요하다.
6. 조회 전용 기능과 응용 서비스
서비스에서 구행하는 추가적인 로직이 없을뿐더러 단일 쿼리만 실행하는 조회 전용 기능이라면 궅이 서비스를 만들지 않아도 된다.
Comments