Spring DDD Architecture 기초

Gogh·2023년 8월 27일
0

Architecture

목록 보기
2/2
post-thumbnail

개발 방식에 따른 아키텍쳐

  • Transaction Script - 스프링 개발의 가장 기초적인 개발 방식
    • 여기서 서비스 로직은 모든 비즈니스 결정을 내리는 로직을 가지고 있다
    • 레포지토리에 직접적으로 접근하는 로직을 가지고 있다
    • 모든 비즈니스 결정 로직이 집약되어 있어 과한 책임을 가지고 있다

Untitled

  • DDD - 도메인 주도 설계(도메인 위주의 개발 방식) Untitled
    • 비즈니스 결정을 내리는 로직이 어느 하나의 도메인에 명확히 종속적이지 않고 애매한 경우 새로운 객체를 만들면 된다(위 그림 예제 코드)
      • 새로운 객체는 유틸 또는 메니저 역할을 하는 객체다
    • 어플리케이션 서비스 로직과 도메인 서비스 로직으로 나누어 지게 된다
    • 어플리케이션 서비스 로직은 비즈니스 결정을 내리는 로직이 아니어야 하고 요청에 대한 결정을 도메인 서비스에 위임하게 된다

추상화의 범위

  • 서비스 로직과 레포지토리 로직의 추상화 Untitled
  • 서비스 객체 → 레포지토리 인터페이스 ← 레포지토리 구현체 → JPA 레포지토리
    • → 도메인 객체는 레포지토리와 연관이 없어야 한다
      • 도메인 객체에서는 핵심 서비스 로직을 구현한다(DDD 개발)
      • 레포지토리로의 접근은 서비스 객체에서 담당한다
    • 의존성 역전이 이루어짐 → 느슨한 결합 → 레포지토리의 스택이 변경되어도 비즈니스 로직에 영향을 주지 않는다
    • 서비스 로직은 레포지토리 인터페이스를 주입받는다
      • 별도의 툴 없이 테스트가 가능 해 진다
    • 레포지토리 구현체는 레포지토리 인터페이스를 상속받고 JPA 레포지토리를 주입 받아 사용한다
    • DB 엔티티와 도메인 엔티티를 분리한것
  • 컨트롤러 & 서비스 로직은 구현체여도 무관하다
    • 서비스와 컨트롤러는 한번 생성으로 영원히 같은 일을 할 수 있는 객체여야 한다

서비스

💡 행위를 적절한 객체로 다듬는 것을 너무나도 쉽게 포기해서 점점 절차적 프로그래밍에 빠지게 되는것이다 ”도메인 주도 설계: 소프트웨어의 복잡성을 다루는 지혜 - 에릭 에반스”

Untitled

  • 왼쪽 그림과 같이 어플리케이션 서비스에서 어떤 도메인에도 종속되기 애매한 비즈니스 결정 로직을 가지고 있어도 상관 없다
    • 하지만, 새로운 객체로 만들지 않음으로서 절차적 프로그래밍에 다가가게 된다
  • 어플리케이션 서비스 & 도메인 서비스
    • 어플리케이션 서비스 - 스프링 서비스 컴포넌트 종속적인 서비스
      • 레포지토리에 접근하는 동작은 어떤 도메인도 들고있기 애매하기에 어플리케이션 서비스에서 구현 하는것이 좋다 생각된다
    • 도메인 서비스 - 비즈니스 결정을 하는 로직, 스프링 서비스 컴포넌트에 종속적이지 않은 서비스
      • Manager, Util과 같은 접미어를 사용된, 혹은 될것 같은 객체는 도메인 서비스일 확률이 높다
      • 도메인으로 분리하지 못하여 Manager,Util 같은 객체로 만든다면 도메인 서비스가 될 것이고, 그 서비스들을 합쳐 하나의 객체로 만들수 있다면 도메인이 된다

        위 말은 사실 이해가 되지 않는다,
        PriceCalculator는 유틸 클래스와 같은 의미로 클래스명을 보고 유추할수 있다. 이 클래스를 Cashier로 변경한다면, 하나의 도메인으로 유추하게 된다.
        클래스의 이름만으로 도메인과 도메인 서비스 여부를 나누고 있지 않은가
        클래스명 만으로 이런 구분을 한다는 것은 애매한 것 같다.
        도메인 서비스란 하나의 레이어로 생각하고 설계를 하는것이 좋을 것 같다.

  • 풍부한 도메인을 만들고 어플리케이션 서비스는 가능한 적고 얇게 만드는 것이 좋다.
  • 한번의 생성으로 영원히 같은 일을 할수 있는 객체가 서비스다.
    • 그래서, 서비스 객체는 불변이어야 한다
      • 생성자 주입을 사용하는 것이 좋다 - 한번 생성으로 일관된 객체를 만들수 있다.
  • 서비스에서의 순환참조는 사실 하나의 컴포넌트라는 의미일 수 있다
    • 공통되는 부분을 하나의 컴포넌트로 분리해 내야 한다

      Untitled

기타

  • JPA N+1에 대한 구조적 해결
    • 레포지토리 구현체에서 N+1 문제가 발생하는 엔티티를 한번에 조회하는 방법
    • 네이티브 쿼리 혹은 QueryDSL과 같은 라이브러리 활용

Untitled

  • 리스트 인터페이스
    • 리스트 인터페이스 형식으로 의존성 주입을 받으면 구현체 모두가 주입된다.

Untitled

  • Local Repository
    • 테스트 용으로 활용하면 좋지만 단점 확인

Untitled

profile
컴퓨터가 할일은 컴퓨터가

0개의 댓글

관련 채용 정보