우테코 레벨 2 미션 중 '장바구니 미션'을 진행하고 있는데요,
최근 저의 가장 큰 고민 중 하나는 '도메인을 어떻게 순수하게 유지할 수 있을까?' 였습니다.
이런 고민을 해결하기 위해 몇 가지 방법을 시도해보게 되었고, 그 과정을 간단하게 기록해보려고 합니다!
1. DIP 적용
우선 저는 순수하게 도메인을 유지시키기 위한 방법으로 DIP를 먼저 떠올렸습니다.
계층형 아키텍쳐를 사용하는 경우, 이를 달성하기 위한 가장 보편적인 방법은 DIP입니다.
비즈니스 레이어에서 Repository나 Dao를 구현하는 영속성 레이어로 향하는 의존성을 DIP를 통해 역전시키면 됩니다.
이렇게 인터페이스를 도메인 패키지 내에 두면, 구현체에 관계없이 비즈니스 패키지는 독립적으로 작동할 수 있게 됩니다.
여기서 주의할 점은, 인터페이스 내 메소드 시그니쳐에 구현체에 대한 어떤 정보가 들어간다면 그것은 DIP를 제대로 적용한 것이 아닙니다.
즉, 의존성을 나타냈을 때 기존에는 아래와 같은 그림이었다면
DIP를 적용한 이후 아래와 같이 의존의 방향이 바뀌게 되었습니다.
이렇게 DIP를 적용하면서 영속성 계층의 구현 변경사항이 도메인에 거의 영향을 미치지 않도록 구성했습니다.
2. 도메인 엔티티, 영속성 엔티티 분리
장바구니 미션에서는 상품 객체가 id 값을 가집니다.
그리고 이 상품 객체의 id가 그대로 표현 영역에 전달되어 보여집니다.
사실상 이 id 값 때문에 도메인 엔티티와 영속성 엔티티가 가지는 데이터가 같아졌는데요,
그렇다고 해서 저는 데이터베이스가 부여하는 ID를 그대로 도메인 엔티티가 가지게 하고 싶지는 않았습니다.
INTEGER 형 ID를 사용하는 데이터베이스를 사용하다가, UUID를 사용하는 데이터베이스로 교체해야 한다면 어떨까요?
데이터베이스의 변경이 도메인 엔티티의 속성을 바꾸게 될 것 같습니다.
아래와 같이요.
// 아래 Product 엔티티가 DB의 아이디를 그대로 사용한다면
public class Product {
private final int id;
...
}
// Database 변경에 따라 변경되어야 한다
public class Product {
private final UUID id;
...
}
따라서 저는 도메인 엔티티와 영속성 엔티티를 완전하게 분리했습니다.
아래처럼 전문적으로 ID를 부여하는 유틸리티 객체를 하나 둬서, Product 엔티티마다 id를 부여했습니다.
public class IdSequencer {
private static int sequence = 0;
public static int get() {
return ++sequence;
}
}
// 사용 시
public static Product generate(ProductDto productDto) {
return new Product(
IdSequencer.get(),
new ProductName(productDto.getName()),
new ProductImage(productDto.getUrl()),
new ProductPrice(productDto.getPrice())
);
}
그리고 DB 테이블의 스키마는 아래처럼 구성했습니다.
CREATE TABLE PRODUCT (
id INT NOT NULL AUTO_INCREMENT,
entity_id INT NOT NULL
...
);
테이블에서 id를 두 개 가집니다.
즉, 이제는 도메인 엔티티를 위한 ID와 데이터베이스를 위한 ID가 따로 존재하게 되었습니다.
이번 미션에서 위 과정들을 통해 도메인을 순수하게 유지할 수 있었습니다.
이제 비즈니스 패키지가 변경되는 순간은 비즈니스 자체가 바뀔 때 단 하나뿐이게 되었습니다.
추가
구글링 해 찾아보니 이미 비슷한 시도를 하신 분이 계셨고, 나중에 참고하면 좋을 것 같아 링크 첨부합니다.
https://matthiasnoback.nl/2018/05/when-and-where-to-determine-the-id-of-an-entity/
'우테코 5기' 카테고리의 다른 글
[레벨 2 미션] 웹 자동차 경주 미션 학습 기록 (0) | 2023.05.07 |
---|---|
[트러블슈팅] Interceptor 생성으로 인해 컨트롤러 테스트가 깨지는 경우 (8) | 2023.05.05 |
우아한테크코스 레벨1 회고 (6) | 2023.04.06 |
[레벨 1 미션] 체스 학습 기록(2) (2) | 2023.04.06 |
[레벨 1 미션] 체스 학습 기록(1) (2) | 2023.04.04 |