DDD(Domain Driven Dvelopment)

sds1vrk·2021년 8월 24일
1

Spring

목록 보기
1/1
  • 도메인이란?

    • 사용자가 프로그램을 사용하는 대상 분야를 도메인이라고 한다.
    • 사용자란? 소프트웨어와 관련된 모든 사람
      • 요리사 → 소프트웨어에서 요리 이미지를 본다면 요리 이미지가 도메인
    • 병원에서 모든 환자의 진료 기록을 보관하고 분석하기 위해 병원 프로그램을 사용
      • 병원에서는 환자 진료 차트 도메인
    • 은행에서는 고객의 자산을 관리하고 보호하기 위해 소프트웨어 사용
      • 은행에서는 고객 리스트 도메인
    • 중고 자동차 판매상은 구매되는 자동차와 판매되는 자동차의 교환으로 자동차 도메인
  • 객체와의 차이점은?

    • 객체는 추상화 또는 구체화할 수 있는 특정 요소만을 표현
    • 도메인은 사용자가 사용하는 모든 것
    • EX) "고양이는 사과를 먹는다"
      • 객체 : 고양이, 사과 / 행위 : 먹는다
      • 도메인 : 고양이, 사과, 먹는다, 고양이는 사과를 먹는다. → 모두 각각 도메인이라고 할 수 있음
    • 따라서 도메인은 사용하는 사용자가 바라보는 관점에 따라 각각을 구분하거나 전체라고 할 수 있음.
    • 실세계에서 사건이 발생하는 집합
  • 왜 도메인 주도 설계가 나왔을까?

    • 객체 지향에서의 핵심은 결국 객체(무언가를 만드는 주체)라고 볼 수 있음
      - 이는 객체들을 어떻게 하면 추려낼 수 있을까?
      - 어떻게 하면 어떤 객체가 필요한지 알 수 있을까?
      - 어떻게 하면 이 객체들이 서로 상호작용할 수 있을까?

      —> 이런 문제를 해결할 수 있는 방법이 도메인 주도 설계

DDD

  • 도메인을 중심으로 하는 개발 방식 → 도메인에 관련된 문제를 해결하는 것
  • 복잡한 도메인을 해결하는 것을 높은 우선순위로 생각해 서비스를 만들어 나가는 방법

→ 도메인의 복잡성을 조금 더 쉽게 다룰 수 있게 도와주는 도구

  • EX) 옷 쇼핑몰

    • 손님들이 주문하는 도메인 (Order Domain)
    • 점주입장에서는 옷들을 관리하는 도메인(Manage Domain)
    • 쇼핑몰 입장에서는 월세, 관리비 등 건물에 대한 관리를 담당 (Building Domain)
  • 이러한 도메인들을 추상화하여 모델링하고 서로 상호작용하며 설계하는 것이 바로 도메인 주도 설계

  • 도메인 모델
    - 특정 도메인을 개념적으로 표현한 것
    - 도메인 모델을 사용하면 여러 관계자 (개발자, 기획자, 사용자 등)이 동일한 모습으로 도메인을 이해할 수 있음.

  • 도메인 주도 설계 아키텍쳐 개요

  • 도메인 모델의 4개의 영역

  • PRESENTATION LAYER : 표현 영역 또는 UI 영역. 사용자의 요청을 받아 응용 영역에 전달하고, 응용 영역의 처리 결과를 다시 사용자에게 보여주는 역할을 한다. (Controller 영역)

    	- 요청을 Service에 전달, 결과를 사용자에게 전달
    • 사용자의 세션을 관리
  • APPLICATION LAYER : 응용 영역. 시스템이 사용자에게 제공해야 할 기능을 구현한다. (Service 영역)
    - Repository로부터 도메인 객체를 구하고 도메인 객체를 사용
    • 트랜잭션 처리
    • 도메인 영역에서 발생시킨 이벤트 처리
  • DOMAIN LAYER : 도메인 영역. 도메인 모델을 구현한다. (이름, 주소, 상품, 주문서 등)
  • INFRASTRUCTURE LAYER : 구현 기술에 대한 것을 다룬다. (외부 API, 데이터베이스, 외부 라이브러리 사용 등)

도메인 주도 설계 기본 요소

  • Entity
    - 실제 DB 테이블과 매핑되어 있는 클래스로, DB 테이블내에 존재하는 컬럼만을 속성(필드)로 갖음
    • 식별자를 갖음
@Getter
@Entity
@NoArgsConstructor
public class Posts {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTIFY)
    private Long id;

    @Column
    private String title;

    @Column
    private String content;

    private String author;

    public Posts(String title, String content, String author) {
        this.title = title;
        this.content = content;
        this.author = author;
    }
}
  • VO (Value Object)
    - 불변성을 갖음. 따라서 DB에서 읽을 값을 VO에 담을 경우, 이 VO 값이 DB 데이터 원본으로써 신뢰할 수 있음.
    • Read Only
    • 값이 같다면 같은 객체로 판단 (소스코드에 Equals와 hash코드를 넣음)
@Getter
public class PostsVO {

    private Long id;
    private String title;
    private String content;
    private String author;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PostsVO postsVO = (PostsVO) o;
        return Objects.equals(id, postsVO.id) && Objects.equals(title, postsVO.title) && Objects.equals(content, postsVO.content) && Objects.equals(author, postsVO.author);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, title, content, author);
    }
}
  • DTO (Data Transfer Object)
    - DTD는 데이터 접근 메소드 외에 기능을 가지지 않음
    • getter, setter 메소드만 갖음
    • 값을 유연하게 변경할 수 있음
    • temp
@Getter
@NoArgsConstructor
public class PostsSaveRequestDto {
    private String title;
    private String content;
    private String author;

    @Builder
    public PostsSaveRequestDto(String title, String content, String author) {
        this.title = title;
        this.content = content;
        this.author = author;
    }
    
    public Posts toEntity() {
        return Posts.builder()
                .title(title)
                .content(content)
                .author(author)
                .build();
    }
}

EX) DTO와 VO 구분

DTO aDTO = new DTO("a DTO");
DTO ADTO = new DTO("a DTO");

VO aVO = new VO("a vo");
VO AVO = new VO("a vo");

// DTO는 값이 같다고 해서 같은 객체로 볼수 없음.
// VO는 값이 같다면 같은 객체로 볼 수 있음.

Client <-DTO-> controller(web) <-DTO-> service <-DTO-> repository(DAO) <-Entity-> DB

도메인 설계 방식

  • 전략적 설계 (개념 설계) 크게

    • 복잡한 도메인의 맥락(Context) 경계를 명확히 정의하는 과정

    • Bounded Context안의 도메인 모델에서 보편 언어를 개발하는 방법

    • 도메인에서 서브 도메인으로 복잡성을 분리

      • 핵심, 지원 도메인 파악
    • 컨텍스트 맵핑 기술을 활용해 여러 개의 Bounded Context를 통합

    • 이벤트 스토밍 기법을 활용해 Bounded Context 식별

    • 도메인 Context 경계를 명확히 하지 않으면 진흙 덩어리 문제 (계속 추가 되는 문제가 발생)가 발생

      • 테스트 구현, 협업에서 문제 발생
  • 전술적 설계 (구체적 설계)

    • 전략적 설계에서 더 상세한 부분(바운디드 컨텍스트 내부) 모델링

    • Model Driven Design

    • 빌딩 블록(패턴)을 사용해 모델링 - Aggregate 패턴

      • Entity
      • VO
      • Service
      • Aggregate
        • 관련 객체를 하나로 묶은 군집
        • 도메인 모델 간의 관계 파악 가능
      • Factory
      • Repository
    • 계층형 아키텍쳐를 통한 도메인 모델 분리

    • 도메인 이벤트를 통해 도메인을 보다 명확히 모델링

출처

도메인 주도설계란
도메인주도설계
https://ppiyo5.tistory.com/21
https://webdevtechblog.com/entity-vo-dto-666bc72614bb
https://velog.io/@gillog/Entity-DTO-VO-%EB%B0%94%EB%A1%9C-%EC%95%8C%EA%B8%B0
https://parkadd.tistory.com/53
https://jordy-torvalds.tistory.com/81
https://wangmin.tistory.com/51
https://coderoom.tistory.com/entry/DB-Entity%EC%99%80-DTO-%EA%B7%B8%EB%A6%AC%EA%B3%A0-VO
https://prinha.tistory.com/entry/DTO-vs-VO-vs-Entity
https://www.youtube.com/watch?v=VIfNipL5KkU

profile
BackEnd Developer

0개의 댓글