일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- RESTClient
- 교육기획팀
- 한국대학생it경영학회
- scheduling messages with rabbitmq
- 자바 ORM 표준 JPA 프로그래밍
- ddd
- delayed message plugin
- Domain Driven Design
- 교육기획팀원
- GitHub Actions
- reactive operaton
- 자동처리
- 영속성
- 객체지향 쿼리 언어
- JPQL
- Spring
- 큐시즘
- 도메인 주도 개발 시작하기
- rabbitmq-delayed-message-exchange
- 30기
- Spring Batch
- 이펙티브자바
- jdbc
- JPA
- kusitms
- java
- springboot
- 최범균
- cicd
- 밋업프로젝트
Archives
- Today
- Total
코딩은 마라톤
[도메인 주도 개발 시작하기] Chapter6. 응용서비스와 표현 영역 본문
표현 영역과 응용 영역
- 표현 영역 : 사용자의 요청 해석, 요청에 상응하는 응용 서비스 실행
- 응용 영역 : 실제 사용자가 원하는 기능을 제공하는 서비스
응용 서비스 역할
- 응용 서비스는 사용자의 요청을 처리하기 위해 리포지터리에서 도메인 객체를 가져와 사용한다.
- 응용 서비스는 도메인 영역과 표현 영역을 연결하는 창구
- 응용 서비스가 복잡하면 서비스에서 도메인 로직 일부를 구현하고 있을 수 있음 → 도메인 로직을 서비스에서 사용하고 있을 수 있음
- 응용 서비스는 트랜잭션 처리 담당
도메인 로직 넣지 않기
도메인 로직을 응용 서비스에 분산해서 구현할 경우 문제점
- 코드 응집성 떨어짐
- 도메인 데이터와 도메인 로직이 한 영역에 위치하지 않기 때문
- 여러 응용 서비스에서 동일한 도메인 로직을 구현할 가능성이 높아짐
응용 서비스 구현
응용 서비스는 표현 영역과 도메인 영역을 연결하는 매개체 역할 → 파샤드 (디자인 패턴)와 유사
응용 서비스 크기
- 한 응용 서비스 클래스에 모든 기능 구현하기 (도메인 별)
- 장점 : 한 도메인과 관련된 기능을 구현한 코드가 한 클래스에 위치하므로 동일 로직에 대한 코드 중복 제거
- 단점 : 서비스 클래스 크기가 커진다
public class MemberService { ... }
- 구분되는 기능별로 응용 서비스 클래스 따로 구현하기
- 단점 : 클래스 개수 많아짐
- 장점
- 코드 품질을 일정 수준으로 유지하는데 도움
- 각 클래스별로 필요한 의존 객체만 포함
public class ChangePasswordService { ... }
만약 각 응용 서비스에서 공통되는 로직이 있다면 별도 클래스로 구현한다.
public final class MemberServiceHelper { ... }
응용 서비스의 인터페이스와 클래스
public interface MemberService {
public void changePassword(...);
}
public class MemberServiceImpl implements MemberService {
... 구현
}
위와 같이 인터페이스를 만들고 구현체에서 구현하는 경우를 많이 봤을 것이다.
인터페이스가 필요한 상황
- 구현 클래스가 여러 개일 때 사용
하지만 응용 서비스의 인터페이스가 두 개 이상의 클래스로 구현될 경우는 거의 없다.
표현 영역
표현 영역의 책임
- 사용자가 시스템을 사용할 수 있는 흐름(화면)을 제공하고 제어한다.
- 사용자의 요청을 알맞은 응용 서비스에 전달하고 결과를 사용자에게 제공한다.
- 사용자의 세션을 관리한다.
값 검증
값 검증은 표현 영역과 응용 서비스에서 수행될 수 있다.
표현 영역에서 값을 검증할 경우, 잘못된 값이 존재하면 사용자에게 알려주고 값을 다시 입력받는다.
응용 서비스에서 각 값이 유효한지 확인할 목적으로 익셉션을 발생할 때, 처음 익셉션이 발생하면 이후 값 검증은 하지 않고 첫 익셉션의 에러만 사용자가 알 수 있다.
이러한 사용자의 불편을 해소하기 위해 여러 에러 코드를 모아 하나의 익셉션으로 발생시킬 수 있다.
@Transactional
public OrderNo placeOrder(OrderRequest orderRequest) {
List<ValidationError> errors = new ArrayList<>();
if (orderRequest == null) {
errors.add(ValidationError.of("empty");
} else {
// 조건 1
errors.add(...)
// 조건 2
errors.add(...)
...
}
if (!errors.isEmpty()) throw new ValidationErrorException(errors);
...
}
스프링 같은 프레임워크는 값 검증을 위한 Validator 인터페이스를 사용한다.
- 표현 영역 : 필수 값, 값의 형식, 범위 등을 검증한다.
- 응용 서비스 : 데이터의 존재 유무와 같은 논리적 오류를 검증한다.
→ 하지만 요즘은 응용 서비스에서 필수 값 검증과 논리적인 검증을 모두 하는 편이다. (응용 서비스의 완성도가 높아지는 이점)
권한 검사
권한 검사는 크게 세 곳에서 할 수 있다.
- 표현 영역
- 인증된 사용자인지 검사
- 예시) 회원 정보 변경 기능
- 서블릿 필터에서 인증 정보를 생성하고 인증 여부를 검사한다.
- 응용 서비스
- 메서드 단위로 권한 검사 수행
- ex) Spring Security - AOP 사용
- @PreAuthorize(”hasRole(’ADMIN’)”)
- 도메인
조회 전용 기능과 응용 서비스
서비스에서 조회 전용 기능을 사용하면 서비스 코드는 다음과 같다.
public class OrderListService {
public List<OrderView> getOrderList(String ordererId) {
return orderViewDao.selectByOrderer(ordererId);
}
...
조회 기능만 존재하기 때문에 추가적인 로직은 존재하지 않는다.
단일 쿼리만 실행하는 조회 전용 기능이기 때문에 트랜잭션 또한 필요하지 않기 때문에 서비스에 로직을 넣지 않고 위 코드를 표현 영역에서 바로 사용한다.
'Backend' 카테고리의 다른 글
[RabbitMQ] Delayed Message Plugin를 활용한 메시지 지연 처리 (SpringBoot) (3) | 2025.02.04 |
---|---|
[도메인 주도 개발 시작하기] Chapter5. 스프링 데이터 JPA를 이용한 조회 기능 (1) | 2024.11.03 |
[도메인 주도 개발 시작하기] Chapter4. 리포지터리와 모델 구현 (2) | 2024.10.13 |
설명에 따른 책임을 이겨낼 것인가? (3) | 2024.10.06 |
[도메인 주도 개발 시작하기] Ch3. 애그리거트 (0) | 2024.09.22 |