전술적 설계 - VALUE OBJECT 와 ENTITY
전술적 설계 - 전략적 설계(모델링) 을 통해서 도출한 결과물을 코드로 변경하는데 필요한 전술적 도구들
90년대 OOP -> 2000년대 DDD, 때문에 DDD 는 OOP 의 영향을 많이 받았다.
객체는 상태와 행위를 가진다.
비지니스 로직을 수행하기 위해서는 객체의 행위를 통해서 이루어져야 한다.
풍푸한 도메인 로직을 가져야 한다.
풍부한 서비스로직은 지양해야 한다.
VALUE OBJECT
의미를 명확하게 표현하거나 두 개 이상의 데이터가 개념적으로 하나인 경우 이용
정말
String
타입으로 우편 번호를 표현할 수 있는가? -> YES!String
타입은 우편 번호인가? -> NO..처음에는 동작하지 않고, 시스템이 성숙해짐에 따라서 기본형 타입을 객체로 대체하게 된다.
값 객체 타입은 불변
모든 객체는 일단 불변이 좋다고 생각하자.
시작부터 불변으로 객체를 만들고, 필요한 경우 가변으로 바꾸는 것으로 생각하자.
서버 자원을 생각하면서 개발하는 시대는 지났다.
예시, Car 의 CarName
위 코드에서
Car
객체를 생성할 때 이름에 대한 제약 조건,Car
객체의 이름을 변경할 때 제약조건이 겹친다. (코드 중복이 발생한다)이를 해결하기 위한 좋은 방법은 공통된 로직에 대한 메서드를 분리하는 방법도 있지만, 해당 필드에 대한
CarName
값 객체를 만들어 해당 객체를 사용하면 무조건적으로CarName
객체를 사용하면 5글자를 넘지 않겠다는 확신을 줄 수 있다. (심리적 안정감)또한,
CarName
객체를 통해서 자동차 이름은 5글자를 넘어설 수 없다는 도메인 로직을 반영할 수 있다.
VALUE OBJECT 는 식별자가 없다? (애매혀;;)
대부분의 책에서는 ENTITY 는 식별자가 있고, VALUE OBJECT 는 식별자가 없다고 한다.
하지만 제이슨은 VALUE OBJECT 도 식별자가 있다고 생각한다.
위 코드에서
new Name("Jason", "Park")
자체로 식별자(값의 동등성, 복합키)로 생각한다.
항상
equals()
,hashCode()
메서드를 오버라이드 할 것을 권고한다.VALUE OBJECT 는 기본적으로 값의 모음 자체가 식별자의 역할을 하기 때문에
equals()
,hashCode()
를 오버라이딩 해주어야 한다.
불변 객체
모든 클래스를 상태를 변경할 수 없는 불변 클래스(immutable class) 로 만들면 유지 보수성이 크게 향상된다.
불변 객체에는 아래의 식별자 변경(identity mutability) 문제가 발생하지 않는다.
불변 객체 장점
불변객체는 객체가 완전하고 상태가 아니면 아예 실패하는 실패 원자성(failure atomicity) 을 가진다.
불변 객체는 시간적 결합(temporal coupling) 을 없앨 수 있다.
스레드 안정성
객체가 여러 스레드에서 동시에(comcurrently) 사용될 수 있고 예측 가능한(predictable) 결과를 보장하는 객체의 품질
단순성(simplicity), 객체가 더 단순해질 수록 응집도는 높아지고, 유지보수는 쉬워진다.
불변 객체의 크기가 작은 이유는 불변 객체의 경우 생성자 안에서만 상태를 초기화할 수 있기 때문이다.
그렇다면 언제 가변 객체(ENTITY)를 사용하는가?
어떤 객체의 값의 변경을 추적해야 하는 경우가 있을 때 사용한다.
ex1, 내가 주소지를 변경해도 내가 변경되지는 않는 것이기 때문에 식별자가 필요하다. (주민등록번호)
ex2, 지폐는 지폐를 추적(위조지폐 여부 확인을 위해?)하기 위해서 식별자가 필요하다. (발생번호, 일련번호)
이런 경우 VALUE OBJECT 를 ENTITY 로 변경한다.
관점(컨텍스트) 에 따라서 ENTITY 변경이 필요 없을수도 있다.
ENTITY
식별자를 갖는다.
객체의 상태 중 해당 객체의 고유한 성질을 표현할 수 있는 상태들을 식별자라고 부른다 .
식별자는 엔티티 객체마다 고유해서 각 엔티티는 서로 다른 식별자를 갖는다.
특정 규칙에 따라 생성 (ex, 날짜 + 일련번호)
UUID 사용
값을 직접 입력
일련번호 사용
ENTITY 에 대한 오해
관점에 따라서 ENTITY 에 의미가 달라진다.
예시1, JPA - Persistence Entity
예시2, DDD - 식별자를 갖는(가변) 객체를 Entity 라고 부른다.
도메인 모델에 set 메서드 넣지 않기
도메인 모델에 getter 메서드와 setter 메서드를 무조건 추가하는 것은 좋지 않은 버릇
특히 setter 메서드는 도메인의 핵심 개념이나 의도를 코드에서 사라지게 한다.
setter 메서드의 또 다른 문제는 도메인 객체를 생성할 때 완전한 상태가 아닐 수도 있다는 것이다.
도메인 객체가 불완전한 상태로 사용되는 것을 막으려면 생성 시점에 필요한 것을 전달해 주어야 한다.
Last updated