You will be fine

<DDD> 도메인 주도 설계의 사실과 오해 part2

by BFine
반응형

조영호님의 도메인 주도 설계의 사실과 오해 part2 세미나를 듣고 정리한 글입니다.! (기억의 왜곡이 있을수 있습니다...)

 a.  DDD 오해

  -  설계한 도메인 모델 본질적이라 생각하지만 실제로는 구현하기 편한 모습으로 만들어나아가는게 맞다..!

      => 코드 짜기 편한 모델을 만드는 과정으로 궁극적인 목표는 코드 복잡성 낮추는것! 

  -  DDD는 수정에 관점을 두기 때문에 통계성 조회 같은 부분과는 관련이 없다. 비즈니스 모델과 구현은 구분해야한다.

      => 이를 같이 녹이려다보니 복잡성이 증가했고 이를 분리하기 위해 CQRS 같은 패턴이 생기게 되었다.

    

 b.  엔티티(Entity)와 값객체(Value Object)

  -  엔티티란 연속성과 식별성을 가지는 객체로 시간이 지나도 구별이 가능해야한다. ex) 그림작품

      => 연속성을 가지기 때문에 계속 상태가 변할 수 있기 때문에 식별자를 기준으로 추적해야한다. (식별자가 같으면 같은 엔티티)

      => 주의 DDD 속의 엔티티는 JPA 엔티티를 의미하는 것이 아니다.

  -  값객체는 식별성이 없는 특징을 가지며 형태와는 관련이 없는 객체다. ex) 돈 ( 네이버페이 만원 == 현금 만원 )

      => 구현에서는 불변 객체 만들기 때문에 변경이 필요하면 매번 새로운 객체를 생성하지만 값이 같기 때문에 값객체로 불린다.

      => 주의할점은 엔티티 내부에서 값객체를 사용한다면 기존 값객체가 아닌 새로운 값객체로 대체하는 것이 맞다.

  -  설계를 하면서 어떤 것은 엔티티고 어떤 것은 값객체가 딱딱 나올것 같지만 그렇지 않다!

      => 이부분은 코드를 잘짜기 위한 방향으로 바꾸어가면 된다. (엔티티의 복잡도를 줄이고 싶으면 값객체로 분리, 가급적 값객체로 만드는것이 좋다)

 

 c. 연관관계

  -  연관관계란 모델 내에 탐색(검색)이 가능한 통로 역할을 한다.  주의할점은 모델에서 연관관계가 있으면 기술적으로도 있어야해는 맞지 않다.! 

  -  연관관계는 최대한 단순화해야한다. 도메인적으로 연관관계가 있어도 구현적으로 필요없으면 제거해도 된다.

      => 개념적으로는 도메인 모델은 양방향이 많지만 가급적 단방향으로 모델링 해야한다. (일대다로 컬랙션을 두기 보다는 다대일로 구현) 

   -  연관관계에서 객체참조는 최대한 줄이는 것이 좋다. (코드레벨에서 객체의 ID 가지고 있다가 다른객체가 찾아줘도 연관관계가 있는것으로 본다.)

 

 d.  애그리거트(Agreegate)

  -  애그리거트는 불변식을 같이 적용해야하는 그룹 단위로 설계해야하며 해당 경계는 최소 단위로 설정하는 것이 좋다.

     => 불변식은 일관성을 유지해야한다는 규칙이며 트랙잭션 일관성, 결과적 일관성(시간에 따라 결과가 맞춰지는것 ex. 배치, 이벤트처리 등) 이 있다.

  -  애그리거트에는 애그리거트 루트가 존재하며 불변식을 검증하는 역할을 해야한다.

  -  애그리거트는 객체들을 그룹으로 묶어 내부에 직접 접근할 수 없도록 캡슐화 해야한다. (루트를 통해 접근)

     =>  정해진게 없기 때문에 비즈니스룰에 따라 애그리거트 경계가 만들어지며 같은 주문 도메인이라도 다를 수 있다.

  -  애그리거트에 해당하는 요소들은 수정이 있던 없던 상관없이 같이 조회되고 같이 저장해야한다.

      => 즉 Eager 로딩해야하는 것이 맞으며 보통 Lazyloading을 사용하는 이유는 애그리거트가 명확하지 않아 어디서 사용될지 모르기 때문일 뿐이다.

  -  코드 구현 관점에서 애그리거트 내부는 어차피 같이 바뀌는 단위이기 때문에 객체 참조를 통해 탐색하거나 양방향으로 설정해도 크게 상관하지 않는다.

 

 e. 리파지토리 (Repository)

  -  리파지토리는 애그리거트를 가져오는 조회(탐색)하는 역할을 담당한다.!!

  -  애그리거트 루트 단위로 추가 되어야 하며 주의할점은 DDD에서 설명하는 리파지토리와 Data JPA의 Repository 와는 다르다.

      => Data JPA의 Repository는  Persistence Layer 성격이 강하기 때문에 DB에서 가져오는게 보인다. (DDD의 엔티티는 테이블이 아니다.)

  -  DDD에서의 리파지토리는 구현의 레벨까지는 알필요없이 마치 컬렉션에 넣고 찾는 것과 같은 성격으로 보면된다. 

 

 f.  팩토리(Factory)

  -  팩토리는 애그리게이트를 만드는 역할을 한다. 각각 만들면 불변식이 깨질수 있기 때문에 팩토리를 사용한다고 보면된다.

     => 경계가 애매하다면 독립적인 팩토리를 만드는것도 방법일 수 있다.!

 

 g.  서비스(Service)

  -  구현레벨에서 로직은 어플리케이션 로직과 도메인로직으로 나누어질 수 있다.

      => 여기서 도메인로직은 다른 부분들이 없어도 독립적으로 동작해야한다.

  -  여기서 서비스는 어플리케이션 로직 즉 플로우(기능의 흐름)을 정리해주는 역할을 한다.

      => 다만 코드를 작성하다보면 도메인 로직인지 어플리케이션 로직인지 가늠이 어려운 경우에는 Domain Service를 만들기도 한다.

 

 h. 느낀점 

  -  DDD에 대해서 애매하게 알고 있었던 것 같은데 세미나를 들으면서 어느정도 정리가 된 것 같고 2시간 넘게 했는데도 오랜만에 재미있게 들었던 것 같다.

  -  내 생각에는 가장 강조하신 부분은 결국 실무에 적용하는 것이기 때문에 코드를 짜기 쉽게 복잡성을 낮추는게 중요하다라고 많이 하신 것 같다.

  -  신입부터 1~2년 때는 뭔가 새로운게 맞고 레거시는 틀려 라는 생각이 크게 있었던것 같은데 요즘 들어서 많이 잘못생각했었구나를 느끼고 있다.

  -  패턴이나 방법론이나 당연히 기준은 있어야 겠지만 어떤 방법론이 요즘 핫하니까 이걸 적용하는게 맞아 이게 아니라 도메인 특성에 맞게 필요하면 적용하는

     것이 올바른 방향인 것 같고 특정 방법을 고집하기 보다는 필요하다면 여러 방법론 & 패턴을 적절하게 섞어보는것도 괜찮지 않을까 싶다. 가장 중요한거는

     코드 작성하기 쉬운지, 처음보는 사람이 보아도 최대한 짧은 기간에 잘 이해할 수 있는지, 간결하게 설명할 수 있는지를 목표로 두는게 좋을것 같다!! 

반응형

블로그의 정보

57개월 BackEnd

BFine

활동하기