[DDD START] 6장 응용 서비스와 표현 영역

David Lee·2023년 12월 10일
0

DDD Start

목록 보기
6/12
post-thumbnail

이 포스트는 📔 도메인 주도 개발 시작하기 책을 읽고 공부한 내용을 정리한 포스트입니다.

6장. 응용 서비스와 표현 영역

6.1 표현 영역과 응용 영역

도메인의 제 기능을 활용하기 위해서는 사용자와 도메인을 연결해 주는 매개체가 필요하다. 여기서 사용자와 도메인을 연결시켜주는 역할을 담당하는 영역이 바로 응용 영역표현 영역이다.

표현 영역은 사용자의 요청을 받아서 해석하는 역할을 하며, 사용자의 요청을 받아 사용하고자 하는 기능을 판별하고 그 기능을 제공하는 응용 서비스를 실행한다.

응용 영역은 실제 사용자가 원하는 기능을 제공하는 영역이다. 사용자의 요청에 대한 기능을 제공하는 주체는 응용 영역의 서비스에 위치한다.

응용 영역에서 사용하고자 하는 메서드 파라미터와 표현 영역에서 사용자에게 전달받은 데이터의 형식은 일치하지 않음으로 표현 영역 → 응용 영역에서 데이터의 변환과 응용 영역 → 표현 영역에서의 데이터의 변환이 필요하다.

6.2 응용 서비스의 역할

응용 영역의 서비스는 사용자가 요청한 기능을 실행하며, 이를 처리하고자 리포지터리에서 도메인 객체를 가져와서 사용한다. 즉 사용자 입장에서 서비스의 역할은 도메인 영역과 표현 영역을 연결해주는 창구 역할로 볼 수 있다.

도메인 로직을 응용 영역도메인 영역에 분산하여 구현하면 발생하는 문제점은 아래와 같다.

  • 코드의 응집성이 떨어진다. (응집도 하락)
    도메인 데이터와 그 데이터를 조작하는 로직이 한 영역에 위치하지 않는다는 것은 도메인 로직을 파악하기 위해 여러 영역을 분석해야하는 불필요함을 남긴다.
  • 여러 서비스에서 도메인 로직이 중복 구현될 가능성이 높다. (코드 중복)
    하나 이상의 서비스에서 도메인 로직의 구현을 위해 동일한 하위 도메인 로직을 구현함으로써 코드 중복을 야기할 수 있다.

소프트웨어의 가치를 높이기 위해서는 도메인 로직을 도메인 영역에 모아서 코드 중복을 줄이고 응집도를 높여야 한다.

6.3 응용 서비스의 구현

응용 서비스를 구현하는 과정에서 고려해야할 점은 아래와 같다.

  • 응용 서비스의 크기

    하나의 서비스에 특정 도메인의 모든 기능을 구현할 것인가? vs 구분되는 기능별로 응용 서비스 클래스르 따로 구현할 것인가?

    하나의 서비스에 특정 도메인의 모든 기능을 구현하는 경우의 장점은 동일 로직에 대한 코드 중복을 제거할 수 있다는 점이다. 중복된 로직을 private 메서드로 구현 및 호출함으로써 중복 로직을 쉽게 제거할 수 있다.
    하지만 하나의 서비스에 모든 기능을 구현하면 서비스 클래스의 크기가 커진다는 단점이 존재한다. 코드 내 연관성이 적은 코드가 많아질 수 있다는 점과 이 부분을 통해 코드 이해의 저하가 발생할 수 있다.

    구분되는 기능별로 서비스를 구현하면 위에서 이야기한 코드의 연관성을 높일 수 있다는 장점이 있다. 그렇다면 동일 로직에 대한 코드 중복을 어떻게 해결할까? 이도 마찬가지로 중첩 로직에 대한 별도 클래스를 구현 및 호출을 통해 활용함으로써 코드의 중복을 방지할 수 있다.

  • 응용 서비스의 인터페이스와 클래스

    응용에 대한 인터페이스를 만들고 이를 상속한 클래스를 만드는 것이 필요할까?

    정답은 아니다. 이다. 명확하게 인터페이스가 필요하지 않은 상황에서는 응용 서비스에 대한 인터페이스를 작성하는 방식이 좋은 선택이라고 볼 수 없다.
    만약 TDD를 활용하여 구현하는 과정에서의 인터페이스 활용은 Mockito와 같은 테스트 도구를 활용하여 테스트용 대역 객체를 만들어 개발을 진행할 수 있기에 인터페이스를 활용할 필요는 없다.

  • 메서드 파라미터와 값 리턴

    다른 영역으로 값을 어떻게 전달할까?

    응용 서비스에서 기능을 실행하는 데 필요한 값을 표현 영역에서 전달받아야 한다. 갑승ㄹ 전달 받을 때 각 값에 대한 개별 파라미터로 값을 전달하거나, 별도 데이터 클래스를 만들어 값을 전달할 수 있다.

    응용 서비스의 결과를 표현 영역에서 사용해야 한다면 서비스의 실행 결과를 그대로 리턴해줘도 되지만, 만약 실행 결과가 애그리거트 객체라면 도메인의 로직 실행을 응용 서비스 외에 표현 영역에서도 할 수 있다는 위험성이 생긴다.
    코드의 응집도가 하락하는 사태가 벌어진다. 그러므로 응용 서비스에서 표현 영역으로 값을 돌려줄 때는 필요한 데이터만 리턴하는 것이 기능 실행 로직의 응집도를 높이는 방법이다.

  • 표현 영역에 의존하지 않기

    응용 서비스의 파라미터를 표현 영역에서 전달받은 값 그대로 사용하면 안될까?

    응용 서비스의 파라미터는 표현 영역에서 전달받는 파라미터와 동일하면 안된다. 이는 결국 표현 영역에 대한 의존을 발생시키기 때문에 테스트 환경에서 응용 서비스만 단독으로 테스트하기가 어려워진다. 혹은 더 나아가 응용 서비스가 표현의 영역까지도 대신할 수 있는 상황이 발생할 수도 있기에 철저하게 응용 서비스가 표현 영역의 기술(파라미터)를 사용하지 않도록 해야 한다.

  • 트랜잭션 처리

    응용 영역에서 트랜잭션 처리는?

    응용 영역에서 트랜잭션을 관리하는 것은 매우 중요한 역할이다.
    프레임워크에서 제공하는 트랜잭션 기능을 적극 활용하는 것이 좋다.

6.4 표현 영역

표현 영역의 책임은 아래와 같다

  • 사용자가 시스템을 사용할 수 있는 흐름(화면)을 제공 및 제어한다.
    웹 서비스의 표현 영역은 사용자의 요청 내용에 대한 응답으로서 제공된다. 사용자가 표현 영역이 제공한 폼에 따른 값을 전송하면 표현 영역은 응용 서비스를 통해 요청을 처리하고 그 결과를 응답으로써 전달한다.

  • 사용자의 요청을 알맞은 응용 서비스에 전달하고 결과를 사용자에게 전달한다.
    표현 영역에서 응용 서비스로 내용을 전달할때 사용자의 요청 데이터를 응용 서비스의 형식에 맞게 변환하여 제공할 수 있다.

  • 사용자의 세션을 관리한다.
    웹에서는 쿠키나 서버 세션을 이용해서 사용자의 연결 상태를 관리하는데 이 과정을 표현 영역이 담당한다.

6.5 값 검증

전달받은 값에 대한 검증은 표현 영역과 응용 서비스 두 곳에서 모두 수행할 수 있다.

원칙적으로는 모든 값에 대한 거증은 응용 서비스에서 처리되어야 한다. 하지만 표현 영역에서 잘못된 값에 대해서 사용자에게 전달 및 재입력의 과정이 필요로 하기에 응용 서비스에서만 모든 값의 검증 처리에는 한계가 존재한다.
표현 영역에서 필수 값과 값으 형식 검사를 진행하고 이를 기반으로 응용 서비스에서는 논리적 오류만 검사한다면 값 검증 과정에서 구현의 편리함이라는 이점을 얻을 수 있다.

  • 표현 영역에서의 값 검증: 필수 값, 값의 형식, 범위, ...
  • 응용 서비스에서의 값 검증: 데이터 존재 유무와 같은 논리적 오류 검증

6.6 권한 검사

사용자의 권한에 대한 검사는 인프라스트럭처 영역을 제외한 모든 영역에서 수행할 수 있다.

  • 표현 영역에서의 권한 검사

    표현 영역에서 할 수 있는 권한 검사는 인증된 사용자인지에 대한 여부를 검사한다는 점이다. Servlet Filter를 활용하여 사용자의 인증 정보를 생성하고 여부를 검사함으로써 권한 검사를 진행 할 수 있다.

  • 응용 서비스에서의 권한 검사

    URL 만으로 접근 제어를 할 수 없는 경우 응용 서비스의 메서드 단위로 권한 검사를 수행해야 한다. 스프링 시큐리티의 AOP를 활용해서 메서드마다 권한 검사를 수행할 수 있는 기능을 추가할 수 있다.

  • 도메인 객체에서의 권한 검사

    도매인 객체 내부에 권한 검사 로직을 구현해야 하기에 구현 방식이 매우 복잡하다.

6.7 조회 전용 기능과 응용 서비스

응용 서비스에서 수행하는 추가적인 로직이 존재하지 않고, 단일 쿼리만 실행하는 조회 전용 기능은 응용 서비스 없이 표현 영역에서 전용 기능에 접근하는 방식을 활용하는 것도 가능하다.

profile
쌓아가기

0개의 댓글

관련 채용 정보