1. 도메인 모델 시작

도메인

 

도메인이란? 개발자 입장에서 소프트웨어로 해결하고자하는 문제 및 관심사를 뜻한다. 

예를 들면 온라인 서점 서비스를 구현한다고 가정할 때 '온라인 서점' 은 소프트웨어로 해결하고자하는 문제 영역인 도메인(Domain)에 해당된다. 또 한 도메인은 하위 도메인으로 다시 나눌 수 있다.

 

다음은 '온라인 서점'의 하위 도메인들을 구성한 그림이다.

 

 

 

도메인 모델

 

도메인모델이란? 기본적으로 도메인 자체를 이해하기 위한 개념 모델이다.

 

도메인을 이해하려면 도메인이 제공하는 기능과 도메인의 주요 데이터 구성을 파악해야 하는데, 이런 면에서 기능과 데이터를 함께 보여주는 객체 모델은 도메인을 모델링히기 적합하다. 객체 모델 뿐만아니라 다이어그램으로 표현, 그래프 등을 통해 모델링을 할 수 있다.

 

개념을 모델링 하고나서 바로 코드에 적용하기 어렵기 때문에 구현 기술에 맞는 구현 모델이 따로 필요하다. 개념 모델과 구현 모델은 서로 다른것이지만 구현 모델이 개념 모델을 최대한 따르도록 할 수는 있다. 

 

 

 

도메인 모델 패턴

 

앞서 나온 도메인 모델이 도메인 자체를 이해하는것이라면 이제부터 살펴보는 도메인 모델은 아키텍처상의 도메인 계층을 객체 지향 기법으로 구현하는 패턴을 말한다.

 

USER <--> UI <--> 응용(사용자 요청기능 수행) <--> 도메인 <--> 인프리스트럭처(ex.DB)

 

도메인 계층은 도메인의 핵심 규칙을 구현한다. 예를 들면 주문 도메인이 있을 때 '출고 전에 배송지를 변경할 수 있다', '주문 취소는 배송 전에만 할 수 있다'는 규칙을 구현한 코드가 도메인 계층에 위치하며 이 규칙을 객체 지향 기법으로 구현하는 패턴이 도메인 모델 패턴이라고 한다.

 

 

엔티티와 밸류

 

요구사항을 통해 도출된 도메인 모델에는 크게 엔티티(Entity)와 밸류(Value)로 구분된다.

 

 

 

엔티티

 

위 그림 도메인 모델 중 Order가 엔티티에 해당된다.

엔티티의 가장 큰 특징으로는 식별자를 갖다는 것이다. 즉, 엔티티 객체마다 서로 고유하다.

 

 

밸류

 

ShippingInfo 클래스는 주문시 받는 사람의 이름, 전화번호, 주소를 갖고있다. 즉, 엔티티와는 달리 식별자가 없으며 오로지 데이터를 표현하기 위한 모델이라고 이해하면 될 것같다.

 

 

도메인 모델에 set메서드 넣어서는 안된다

 

@Getter
@Setter
public class Order {
    private Orderer orderer;
    private OrderState orderState;
    
    public Order() {
    
    }
}

 

위와 같은 도메인 모델이 있을 때 다른 모델에서 Order 모델을 인스턴스화 한다고 가정해보자.

 

public class Demo {
    ...
    
    public void demo() {
        Order order = new Order();
        order.setOrderState(OrderState.PAYMENT_WAITING);
        ...
    }
}

 

demo 메서드에서 생성된 order 객체는 완전하다고 할 수 있을까? 코드를 개념적인 관점으로 봤을 때 주문의 상태는 초기화 되었지만 주문자가 누군지 모르는 상태이다. 

 

개선 방안으로는 setter 메서드를 제거, Order 클래스의 디폴트 생성자를 private로 선언하여 외부로 부터 무분별한 생성을 막고 Order 클래스가 완전한 상태로 인스턴스화 될 수 있도록 필요한 인수들을 넘겨주는 생성자 또는 팩토리 메서드를 정의하면 된다. 다음과 같이 말이다.

 

public class Order {
    private Orderer orderer;
    private OrderState orderState;
    
    private Order() {}
    
    public Order(Orderer orderer, OrderState orderState) {
        this.orderer = orderer;
        this.orderState = orderState;
    }
    //또는
    public static Order of(Order orderer, OrderState orderState) {
        Order order = new Order();
        order.orderer = orderer;
        order.orderState = orderState;
        return order;
    }
}

 

추가적인 내용으로 객체지향설계에 따르면 Order는 orderer와 orderState의 정보를 가지고 있는 정보 전문가다. 즉, 정보 전문가로서 Order가진 메시지에서 Order가 가진 정보(상태, orderer, orderState)를 사용하고 이 메시지의 내부 구현은 외부로 부터 숨기며 퍼블릭하게 제공해야한다. 외부의 '어떤 모델'은 Order가 가진 상태를 직접 변경하는 등 관여해서는 안되며 메시지 구현의 책임은 오로지 Order에게 맡겨야한다. 그리고 이 '어떤 모델'은 Order가 제공해주는 퍼블릭 인터페이스를 통해 메시지를 보내야(메서드 호출) 한다.

 

'📚 Book > DDD Start!' 카테고리의 다른 글

7. 도메인 서비스  (0) 2020.08.12
6. 응용서비스와 표현영역  (0) 2020.08.09
3. 애그리거트  (4) 2020.07.19
2. 아키텍처 개요  (2) 2020.07.12