DDD 철저 입문 02. 값 객체

강준혁·2022년 9월 22일
0

DDD 철저 입문

목록 보기
2/6
post-thumbnail

값 객체란?

프로그래밍 언어에는 원시 데이터 타입이 있다. 이것만을 이용해 시스템을 개발할 수도 있지만 때로는 시스템 특유의 값을 정의해야 할 때가 있다. 이러한 시스템 특유의 값을 표현하기 위해 정의하는 객체를 값 객체라고 한다.

값의 성질과 값 객체 구현

값의 성질로는 다음 세가지를 꼽을 수 있다.

  • 변하지 않는다
  • 주고받을 수 있다
  • 등가성을 비교할 수 있다

값의 불변성

값이 수정이 가능하다면 다음과 같은 일이 발생할 수 있다.

"안녕하세요".changeTo("Hello");
console.log("안녕하세요"); // Hello 가 출력된다.

교환 가능하다

값 객체는 불변이기 때문에 대입문을 통한 교환 외의 수단으로는 수정을 나타낼 수 없다.

** 잘못된 수정의 예시

let name = new Name("Joonhyuk", "Kang");
name.changeFirstName("Gildong");

** 올바른 수정의 예시

let name = new Name("Joonhyuk", "Kang");
name = new Name("Gildong", "Kang");

등가성 비교 가능

값은 값끼리만 비교해야 하며 값의 속성을 꺼내어 비교하는 것은 맞지 않다.

1.value == 0.value // 이는 부자연스럽다.
const name1 = new Name("A", "B");
const name2 = new Name("C", "D");
name1.firstName === name2.firstName // 이 또한 위와 같은 상황이다.

값 객체가 되기 위한 기준

시스템에서 사용되는 개념 중 어디까지 값 객체로 만들어야 하는가는 어려운 문제이다.

// 예시 1. FullName 하위는 원시 타입으로 표현하는 경우
class FullName {
  private String firstName;
  private String lastName;
}

// 예시 2. 하위 속성까지 값 객체로 표현하는 경우
class Fullname {
  private FirstName firstName;
  private LastName lastName;
}

도메인 모델로 선정되지 못한 개념을 값 객체로 정의해야 할지에 대한 기준은 "규칙이 존재하는가" 와 "낱개로 다루어야 하는가" 가 될 수 있다.

행동이 정의된 값 객체

값 객체에서 중요한 점 중 하나는 독자적 행위를 정의할 수 있다는 점이다.

값 객체는 데이터와 더불어 그 데이터에 대한 행동을 한 곳에 모아둠으로써 자신만의 규칙을 갖는 도메인 객체가 된다.

// 행동을 가지는 값 객체
const money1 = new Money(1000, "USD");
const money2 = new Money(2000, "USD");
const result = money1.add(money2);

값 객체 도입시의 장점

표현력의 증가

// 원시 타입을 사용하는 경우
function(String modelNumber) { ... }
// 값 객체를 사용하는 경우
function(ModelNumber modelNumber) { ... }

값 객체를 사용하는 경우 modelNumber 에 어떤 법칙을 가진 값이 들어가야 하는지 직관적으로 알 수 있다.

무결성의 유지

시스템에는 각 값이 준수해야 할 규칙이 있으며 값 객체를 활용하면 이를 유연하게 처리할 수 있다.

class FullName {
   private firstName;
   private lastNAme;
   constructor(firstName, lastName) {
     if (!firstName) {
       // 적절한 예외 처리
     } 
   }
}

로직을 한 곳에 모아두기

값에 대한 무결성 검사 혹은 특정 행동들을 외부가 아닌 값 객체 내부로 위치시킴으로서 DRY 원칙을 지킬 수 있다.

profile
백엔드 개발자

0개의 댓글