DDD 정리. 1부
도메인 주도 설계 (Domain Design Driven)
(개인적인 의견.)
도메인 주도 설계
도메인 주도 설계란 도메인( 문제를 해결하려는 영역 ),을 개발자, 기획자, 도메인 전문가(실무자) 들과의 원활한 커뮤니케이션을 이용하여, 도메인 객체를 설계(복잡성과의 끊임없는 전투) 하는 것을 말한다. 그로 인해 코드는 오랜 시간이 지나도 레거시로 남지 않게 되고, 코드를 보다 직관적으로 이해하기 쉽도록 만들어 준다.
원할한 커뮤니케이션 ( *Ubiquitous Language *) 를 통하여 도메인에 대해서 고민하고 설계하는 것을 말한다.
한마디로 실무자와 기획자 개발자가 서로 알아 들을 수 있는 내용으로 도메인에 대해 의논하고 설계하는 것. (올바르지 않는 용어로 도메인을 설계를 한다면 우리가 처음에 해결하고자 하는 도메인 영역에서 멀어진다.)
기존 UML 설계에 대해서는 트랜젝션 영역등을 설계 문서 내에서 표현하기 어려운 점이 있고,
설계를 문서형태로 남기면 개발자가 코드를 작성하면서 문서를 최신화 하지 않으면 도메인과 멀어진다.
ex)
주문단계
주문 -> 결제 -> 배송준비 -> 배송 -> 배송완료
STEP1 -> STEP2 -> … -> STEP5
보다
PRODUCT_ORDER -> PAYMENT -> PREPARE_DELIVERY -> … -> COMPLETE_DELIVERY
가 좀더 도메인과 어울리다는 것.
도메인 주도 설계를 하다보면 좀더 코드를 객체지향적으로 작성할 수 있다.
물론 우리가 작성하는 코드에서도 객체지향적으로 설계 및 코딩은 되지만, 정작 Model로 만든 객체는 객체지향적 설계에서 멀어진다.
또한 여러 도메인 측면 중에는 객체보다는 행동(action)이나 연산(operation)으로 좀더 명확하게 표현 되는 것도 있는데, 이런 것들은 Entity나 Value Object에서 억지로 맡기 보다는 Service로 표현하는 편이 나을 때가 있다. Service는 클라이언트 요청에 대해 수행되는 뭔가를 의미한다.
Entity 객체는 식별성을 갖는 객체이다.
Value Object 불변적으로 다루며 식별성이 아닌 엔티티의 속성인 객체이다.
Entity
- 속성이 아닌 식별성을 기준으로 정의되는 도메인 객체.
ex) DB , ERD
Value object
-
식별성이 아닌 속성을 이용해 정의되는 불변 객체
-
모든 것이 식별성을 부여하고 Entity로 관리한다면 복잡성 증가
-
과거 Java의 DTO(Data Transfer Object) 패턴의 Value Object과 관계 없음.
-
Entity와 Value Object를 구별하는 첫 번째 조건은 식별성 ( ID)
-
식별성을 가지만 Entity 그렇지 않으면 Value Object
Service
-
Domain Object에서 위치시키기 어려운 operation을 가지는 객체
-
여러 Domain Object 다루는 연산 Service의 오퍼레이션은 일반적으로 tateless
-
Domain Object에 해당되는 역할을 Service operation으로 만드는 경우 도메인 역할을 침범하여 강 결합이 일어남.
Module
-
유사 작업 및 개념을 그룹화 하여 복잡도를 감소시키는 기법
-
응집도가 높은 모듈은 모듈간의 관계는 약 결합.
-
Java로 구현하는 경우 Package로 구성될 수 있다.
( 단위 묶는 부분을 이야기 하는 것 같음)
Aggregate
-
연관된 Entity와 Value Object의 묶음. 일관성과 트랜잭션, 분산의 단위, 캡슐화를 통한 복잡성 관리
-
예를 들어 쇼핑몰 사이트에서 주문 Entity내에 배송주소 정보를 우편번호 주소1, 주소2, 상세주소 이런식으로 각 컬럼으로 정의하는 것이 아니라, 주소라는 Value Object를 별도로 작성하고 주문 Entity는 주소 Value Object를 포함하는 방식으로 관계 일관성 및 단순화를 유지한다.
Factory
-
복잡한 Entity의 생성 절차에 캡슐화 할 수 있는 개념
-
생성하기 복잡한 Aggregate의 일관성 유지
-
생성시 Aggregate의 일관성 유지
Repository
-
도메인 영역과 데이터 인프라스트럭쳐 계층의 분리하여 데이터 계층에 대한 결합도를 낮추기 위한 방안
-
생성된 Aggregate에 대한 영속성 관리, 조회, 등록, 수정, 삭제시 Aggregate의 일관성 유지
-
DB 및 데이터 저장소의 데이터를 조회하고 저장하는 경우 Repository를 활용한다.
Domain Service
- 특정 엔티티에 속하지 않은 도메인 롲기을 제공한다. ‘할인 금액 계산’은 상품, 쿠폰, 회원 등급, 구매 금액 등 다양한 조건을 이용해서 구현하게 되는데, 이렇게 도메인 로직이 여러 엔티티와 밸류를 필요로 할 경우 도메인 서비스에서 로직을 구현한다.
Entity 객체와 Value Type의 구분.
Entity 객체는 getter, setter를 허용하는 반면.
Value Type은 불변형으로 사용한다.
불변형(immutable) 이란?
객체 생성자 및 getter는 존재하지만, setter가 존재하지 않는 클래스.
setter가 존재하지 않기 때문에 변경에 대해서 안전하다.
멀티쓰레드 환경에서 안전하게 사용 할 수 있다.
참고사항들
객체 지향적 설계?에 대해서는 아래에 정리해둔 내용과 연속된다.
http://kkforgg.blog.me/220861095879
우선 기존에 웹 개발을 계속해왔던 나는 자바에서 제공해주는 자료 구조 외에 새로운 객체를 만들어서 활용…
혹시 누구는 우습게 보이는 내용일지 모르지만 본인은 많은 것을 느끼게 해줬다.
간단한 설계를 예로 들자면,
‘코드 관리’ 라는 기능을 만든다고 했을 때, 우리가 설계한 DB 스키마는 아래와 같이 만들었다.
 위와 같이 1대 다 관계로 코드 라는 부분을 구현하게 된다면, 객체 설계는 아래와 같을 것이다.
class Code { private String code_id; List codeDetails; } // ~~ class CodeDetail { private String code_id; private String code; } // 1 : n 관계이기 때문에 위와 같이 객체를 설계 할 수 있다. // ~~ Service ---------- public Code findCode(String codeId) { Code code = codeDao.findCode(codeId); if(code == null) { // throw Exception } List codeDetails = codeDao.findCodeDetail(code); if(codeDetails != null) { code.setCodeDetails(codeDetails); } } 별 내용은 아니지만, 코드 ID를 알면 해당 객체에 대해서 설정한 관계에 따라서 가져 올 수 있다는 이야기다.
위와 같이 도메인으로 설계를 하다보면 객체들의 관계를 이해할 수 있다.
참고
mybatis 에서 orm처럼 사용해보기 아래 링크
http://lyb1495.tistory.com/110
http://lyb1495.tistory.com/110