HttpAPI(대충 RestAPI의 제약을 다 따르지는 않는 설계) 의 EndPoint 하나를 통해서 여러가지를 동시에 변경할 수 있도록 일부러 만들었던 경우가 많았습니다
class ChoiceQuestion extends Question {
constructor({ ...data }: CreateQuestionRequestDto) {
this.data = data;
this.validate();
}
private validate(): void {
//Something
}
같은 무언가가 있었을 경우, 조건에 따라서 추후 검증 로직이 변화할 수도 있고, 저장 방식이 바뀌는 상황이었습니다
이런 상황에서 세부사항을 직접 접근할 수 있도록 EndPoint를 만들 경우 데이터가 의도한 상황대로 쌓이지 않을 수 있습니다
이를 해결하기 위해서 EndPoint는 Question에만 열어두고, 그 세부 사항은 무조건 Question을 통해서만 접근하도록 API설계를 했던 상황이 있었는데, 어그리거트 루트와 되게 유사하게 사용했던 경우라고 생각합니다
요즘에는 대부분의 테스팅 프레임워크가 클래스를 모킹할 수 있고, 메서드도 모킹할 수 있기에, 단순히 테스팅 용도로만 사용할 경우 커다란 메리트가 없다고 느껴지기도 함
2가지 장점이 생각나는데
1. 만약 단위테스트를 전체 애플리케이션의 로딩이 필요한 통합 테스트로 바뀌는 상황이 발생한다면 이런 부분에 있어서는 장점이 있을 수 있을 것이라고 생각함
의존성의 방향이 물론 중요하다지만, 과연 그게 그렇게 중요한가? 라는 생각이 있었습니다
이때 자바의 멀티모듈 설계를 떠올리면 그 장점이 있다고 생각합니다
멀티 모듈시 패키지 의존성이 양방향이면 import가 안 되도록 설정이 되는 방식을 통해서 1차적으로 모듈의 의존성을 끊을 수 있다는 점이 커다란 장점이라고 생각합니다
만약 domain안에 repository 인터페이스가 없고, infrastructure 안에 있다면, domoain과 infrastructure안에 양방향 의존성이 생기기에, 관리하기 힘들 수 있습니다
https://techblog.woowahan.com/2637/
배민 멀티모듈 설계에서 domain부분이
repository, entity, 도메인서비스 이렇게가 들어간다고 적혀 있는데요
도메인 모델 속에 @Entity, @Embeddable 같은 코드가 무조건 들어갈 수밖에 없는 설계가 되는 경우가 많다고 생각합니다
이때 사실 infrastructure을 의존하고 있는게 아닌가? 라는 생각이 들 수도 있지만
infrasturcture 부분을 알아서 만들어주기에, 실제 작성할 필요가 없다는 점에서 infrastructure에 무조건 의존한다고 보기에는 살짝 애매하다고 볼 수도 있고
이 부분을 제거한다면 Entity 를 불러오고, 저장하는 과정이 너무너무 어려워지고, private을 통해 숨기기가 힘들어지는 경우가 많기에, 넣어도 된다고 생각합니다
루트 단위에서 적절한 처리가 필요하다는 내용이 있음
그 내부 구현은 어떻게 되든 전혀 상관 없음
응용 계층에서 하나의 트랜잭션에서 여러 루트를 다루는 쪽이 더 깔끔할 경우가 많음. 한 애그리거트는 하나만 다루는 방향으로 작성
이때 팀 표준, 기술 제약, UI 구현의 편리일 때 다른 트랜잭션을 호출하도록 허용한다
이때 애그리거트단위로 조회시 장점이 db를 바꾸기가 쉽다
최적화 할 부분이 명확해지기에 다른 외부 구현을 어떻게 되든 상관없이 확실하게 보장한다는 장점이 있다
이때 로직이 응용 서비스 레이어로 가게 되는 문제가 있음
이를 팩토리를 통해서 래핑하는 것이 가능함
public class Store{
public Product createProduct(ProductId newProductId, ProductInfo pi){
if(isBlocked()) throw
return ProductFactory.create(new ProductId,getId(),pi)
}
}
이때 애매한 부분이 생기는데, store 내부에서 검증 로직을 진행하는 과정을 거치지 않고, 바로 ProductFactory 를 호출해버리는 경우가 생길 수 있음
이런 식으로 문제가 될 수 있기에,
멀티 모듈이라면, product 모듈이 바깥에서 안 보이도록,
단일 모듈이라면 package private 같은 안전망을 두고
애그리거트 루트의 크기를 줄이는 쪽이 좋아보임
root
|-- my-parent
| |-- build.gradle
| |-- settings.gradle
| |-- module-a
| | |-- build.gradle
| | |-- submodule-aa
| | | |-- build.gradle
| |-- module-b
| | |-- build.gradle
멀티 모듈설계와 헥사고날 아키텍처를 동시에 적용한 프로젝트