주난v 개발 성장기

[DDD START!] 2장. 아키텍처 개요 본문

개발 성장기/DDD

[DDD START!] 2장. 아키텍처 개요

주난v 2020. 5. 7. 17:47

네 개의 영역

출처 : https://github.com/scratchstudio/ddd-start/wiki/02.-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%EA%B0%9C%EC%9A%94

  • 표현 영역

    • 사용자의 요청을 받아 응용 영역에 전달

    • 응용 영역의 처리 결과를 다시 사용자에게 전달

  • 도메인 영역

    • 도메인 모델 구현

    • Order, OrderLine 등이 도메인 모델 영역에 위치한다.

    • Entity, Value Object

  • 인프라스트럭처 영역

    • 구현 기술

    • RDB, SMTP, Queue

계층 구조 아키텍쳐

  • 도메인의 복잡도에 따라 응용과 도메인을 분리하기도 하고, 합치기도 한다.

  • 계층 구조는 상위 계층에서 하위 계층으로만 의존하고, 역으로는 발생하지 않는다.

  • 응용 영역과 도메인 영역은 DB나 외부 시스템 연동을 위해 의존하나, 응용에서 도메인을 무조건 의존 할 필요는 없다.

  • 결국, 표현 - 응용 - 도메인 계층은 모두 인프라스트럭처에 의존하게 되고, 별도의 외부 기술(가격 할인 등)과 같은 것이 추가 된다면..

    • 테스트의 어려움

    • 기능 확장의 어려움

DIP

 

  • calculateDiscountService는 고수준 모듈

    • 고수준 모듈의 기능을 구현하려면, 하위 기능이 필요

  • 고수준 모듈이 동작하려면 결국 저수준 모듈을 사용해야 한다.

    • 그러나, 아까와 같은 문제(구현 변경, 테스트 구현의 어려움)이 발생한다.

  • 해결법? DIP!!!

    • 저수준 모듈이 고수준 모듈에 의존하도록 바꾼다....???

      • 추상화 인터페이스!!!

public interface RuleDiscounter {
	public Money applyRules(Customer customer, List<OrderLine> orderLines);
}

public class CalculateDiscountService {
	private RuleDiscounter ruleDiscounter;
    ...
    고객 정보 조회하여.. 처리
}

public class DroolsRuleCounter implements RuleDiscounter {
	// 외부 알고리즘 적용
}

...

RuleDiscounter rule = new DroolsRuleDisCounter();
CalculateDiscountService service = new CalculateDiscountService(rule);

 

"고차원 모듈은 저차원 모듈에 의존하면 안된다. 이 두 모듈 모두 다른 추상화된 것에 의존해야 한다."

"추상화된 것은 구체적인 것에 의존하면 안된다. 구체적인 것이 추상화된 것에 의존해야 한다."

"자주 변경되는 구체(Concrete) 클래스에 의존하지 마라"              

"자신보다 변하기 쉬운 것에 의존하지 마라"

로버트 C 마틴

 

 

도메인 영역의 주요 구성요소

  • 엔티티 - 식별자

    • 데이터를 담는 구조

    • 기능을 구현하고, 캡슐화해서 데이터의 임의 변경을 막는다.

  • 밸류

    • 2개 이상의 데이터가 개념적으로 하나인 경우 밸류 타입을 이용해서 표현할 수 있다.

  • 애그리거트 - 관련된 엔티티와 밸류 객체를 하나로 묶은 것 

    • 관련 객체 군집 단위로 정리

    • 애그리거트 간의 관계로 도메인 모델 이해, 구현 가능

    • 애그리거트 루트(ex. Order)

  • 리포지터리 - 도메인 모델의 영속성을 처리

    • 리포지터리 인터페이스는 도메인 모델 영역

    • 구현 클래스는 인프라스트럭처 영역

  • 도메인 서비스 - 엔티티에 속하지 않은 도메인 로직 제공

 

응용서비스 - 리포지터리 관계

응용서비스 관점

- 응용 서비스는 필요한 도메인 객체를 구하거나 저장할 때 리포지터리를 사용한다. (@Service ??)

- 응용 서비스는 트랜잭션 관리, 트랜잭션 처리는 리포지터리 구현 기술에 영향

 

리포지터리 관점

- 애그리거트를 저장하는 메서드

- 애그리거트 루트 식별자로 애그리거트를 조회하는 메서드

 

 

모듈 구성