ddd start 1장

17
DDD start 1도메인 모델 시작 아꿈사 송성곤

Upload: sung-gon-song

Post on 13-Jan-2017

282 views

Category:

Software


10 download

TRANSCRIPT

DDD start

1장 도메인 모델 시작아꿈사 송성곤

도메인(domain)➢ 소프트웨어로 해결하고자 하는 문제 영역

회원 혜택

주문카탈로그

리뷰 정산

결제

배송

[그림1] 온라인 서점 도메인의 하위 도메인

도메인 모델➢ 도메인 모델은 특정 도메인을 개념적으로 표현한 것❖ 객체를 이용한 도메인 모델

➢ 도메인이 제공하는 기능과 도메인의 주요 데이터 구성 파악하는 데 적합

❖ 상태 다이어그램을 이용한 도메인 모델

➢ 도메인 규칙을 이해하는 데 적합

하위 도메인과 모델➢ 하위 도메인마다 별도로 모델을 작성

○ 각 하위 도메인이 다루는 영역은 서로 다르기 때문에 같은 용어라도 하위 도메인 마다 의미가 달라질 수 있다.

○ 그렇기 때문에, 여러 하위 도메인을 하나의 다이어그램에 모델링하면 안된다.

도메인 모델 패턴➢ 아키텍처상의 도메인 계층을 객체지향 기법으로 구현하는 패턴

사용자인터페이스(UI) 또는 표현(Presentation)

사용자의 요청을 처리하고 사용자에게 정보를 보여준다. 여기서 사용자는 소프

트웨어를 사용하는 사람뿐만 아니라 외부 시스템도 사용자가 될 수 있다.

응용(Application) 사용자가 요청한 기능을 실행한다. 업무 로직을 직접 구현하지 않으며 도메인

계층을 조합해서 기능을 실행한다.

도메인 시스템이 제공할 도메인의 핵심 규칙을 구현한다.

인프라스트럭처

(Infrastructure)데이터베이스나 메시징 시스템과 같은 외부 시스템과의 연동을 처리한다.

도메인 모델 패턴public enum OrderState {

PAYMENT_WAITING {

public boolean isShippingChangeable() {return true;

}},

PREPARING {public boolean isShippingChangeable() {

return true;}

},

SHIPPED, DELIVERING, DELIVERY_COMPLETED;public boolean isShippingChangeable() {

return false;

}

}

개념 모델과 구현 모델➢ 개념 모델은 순수하게 문제를 분석한 결과물이다.➢ 프로젝트 초기에는 개요 수준의 개념모델로 도메인에 대한 전체 윤곽을 이해하는데

집중하고, 구현하는 과정에서 구현 모델(소프트웨어 설계?)로 점진적으로 발전시켜 나가야 한다.

도메인 모델 도출➢ 천재 개발자라 할지라도 도메인에 대한 이해없이 코딩을 시작할 수는 없다. ➢ 기획서, 유스케이스, 사용자 스토리와 같은 요구사항과 관련자와 대화를 통해서 도메인을

이해하고 이를 바탕으로 도메인 모델 초안을 만들어야 비로소 코드를 작성할 수 있다.➢ 도메인을 모델링할 때 기본이 되는 작업은 모델을 구성하는 핵심구성요소, 규칙, 기능을

찾는 것이다. 이 과정은 요구사항에서 출발한다.

문서화

➢ 문서화를 하는 주된 이유는 지식을 공유하기 위함이다. ➢ 전반적인 기능 목록이나 모듈구조, 빌드 과정은 코드를 보고 직접 이해하는 것보다 상위

수준에서 정리한 문서를 참조하는 것이 소프트웨어 전반을 빠르게 이해하는데 도움이 된다.

➢ 코드를 보면서 도메인을 깊게 이해하게 되므로 코드자체도 문서화의 대상이 된다.➢ 도메인 관점에서 코드가 도메인을 잘 표현해야 비로소 코드의 가독성이 높아지며

문서로서 코드가 의미를 갖는다.

엔티티와 밸류➢ 도메인 모델은 크게 엔티티(Entity)와 밸류(Value)로 구분할 수 있다. ➢ 엔티티와 밸류를 제대로 구분해야 도메인을 올바르게 설계하고 구현할 수 있다.

엔티티

❖ 엔티티(Entity)는 영속성(continuity)과 식별성(identity)을 가진다.

➢ 예를 들어 주문이라는 엔티티는 레파지토리에 저장될 수 있고 주문번호라는 식별자를 가진다.

❖ 리포지터리(repository)

➢ 도메인 객체를 데이터베이스에 저장할 때 사용하는 구성요소이다 .

엔티티 식별자 생성➢ 엔티티의 식별자를 생성 시점은 도메인의 특징과 사용하는 기술에 따라 달라진다. ➢ 식별자생성 방식

○ 특정규칙에 따라 생성○ UUID 사용○ 값을 직접 입력

○ 일련번호 사용(시퀀스나 DB의 자동 증가 칼럼 사용)

밸류 타입➢ ShippingInfo 클래스의 receiverName필드와 receiverPhoneNumber필드는 서로 두

데이터를 담고 있지만 두 필드는 개념적으로 받는사람을 의미하다.➢ 밸류 타입은 개념적으로 완전한 하나를 표현할때 사용한다. 예를 들어, 받는 사람을 위한

밸류 타입인 Receiver를 다음과 같이 작성할 수 있다.

public class ShippingInfo {private String receiverName; private String receiverPhoneNumber;private String shippingAddress1;private String shippingAddress2; private String shippingZipcode;

public class Receiver {

private String name;

private String phoneNumber;

받는 사람

public class Address {

private String address1;

private String address2;

private String zipcode;

주소

참조 투명성과 관련된 문제Money 객체 price가 불변 객체가 아니며 setValue로 변경될 수 있음

외부에서 set 메서드를 사용할 수 없도록 해야 한다.

set메서드를 구현해야 할 특별한 이유가 없다면 불변 타입의 장점을 살릴 수 있도록 밸류 타입은 불변으로 구현한다.

Money price = new Money(1000);

OrderLine orderLine = new OrderLine(product, price, 2);

price.setValue(2000);

-> price = 1000, quantity = 2

-> price = 1000, quantity = 2

도메인 모델에 set 메서드 넣지 않기데이터 필드에 대한 get/set메서드를 습관처럼 작성

도메인 지식을 코드로 구현하는 것이 자연스럽다.

Public class Order {

Public void changeShippingInfo(ShippingInfo newShippingInfo)

Public void completePayment(OrderState state)

Public class Order {

Public void setShippingInfo(ShippingInfo newShippingInfo)

Public void setOrderState(OrderState state)

엔티티 식별자와 밸류 타입엔티티 식별자를 밸류 타입을 사용해서 의미가 잘 들어나도록 할 수 있다.

String타입의 orderId를 OrderNo 밸류타입으로 선언

Public class Order {

Private String orderNumber;

Public String getOrderNumber() {

Return orderNumber;

}

Public class Order {

Private OrderNo id;

Public OrderNo getId() {

Return id;

}

도메인 용어➢ 코드를 작성 할 때 도메인에서 사용하는 용어를 코드에 반영하자.

public OrderState {

STEP1, STEP2, STEP3, STEP4, STEP5, STEP6

}

public enum OrderState {PAYMENT_WAITING ,

PREPARING ,

SHIPPED, DELIVERING, DELIVERY_COMPLETED;

}