본문 바로가기

ETC

Value Object 가 최고다.

 

사람의 나이를 나타날때 어느 자료형을 사용해야할까?

1. Interger
2. Boolean
3. String

정답은 셋다 아니다. 나이를 나타내는 타입 Age 를 만들어서 사용해야한다.

 

value object

코드의 유지보수와 가독성을 향상시키며 모델의 표현력을 높일수있는 value object 는
도메인에서 한개 또는 그 이상의 속성을 묶어 특정한 값을 나타내는 객체를 의미한다.
 
value object 의 특징 및 장점으로 는
불변성, 동등성, 자가 유효성, 휴먼 에러 방지 가 있다

불변성

한번 생성되면 그 값을 변경하지 못하게하여 중간에 변경되지 않는 안정성 과
다중 스레드 환경에서 안전하게 사용이 가능하다.

 

public class Age {
    private int value;

    public Age(int value) {
        this.value = value;
    }
    public int getValue(){
        return value;
    }
    public Age happyBirthday(){
        return new Age(getValue() + 1)
    }
}

동등성

같은 타입의 객체를 두개만들었을때 이를 같게하는것이다.

 

Age age1 = new Age(20);
Age age2 = new Age(20);

 

타입도 같고 내부의 속성값도 같은 두 객체가 있다면 같은 객체로 취급을 하고싶을것이다.
이를 equals, hash code 를 재정의 하여 구현할수있다.

자가 유효성

value object 스스로 의미있는 값만 허용하도록 한다.
 
만약 나이를 나타내는 타입을 Integer 로 하였다면
나이 변수 근처에는 항상 나이가 음수는 아닌지 노심초사 하면서 검사하는 코드가 붙어있을꺼다.
하지만 value object 생성자 안에서 스스로 음수를 검사하여 생성할수없게한다면
걱정 뚝

 

public class Age {
    private int value;

    public Age(int value) {
        if(value < 1) throw new IllegalArgumentException();
        this.value = value;
    }
}

휴먼에러 방지

원시 타입을 사용하다보면 다양한 실수가 나온다.
대표적으로 같은 자료형 여러개를 메소드에 전달할때 인것같다.

 

void execute(String name, String address, String phone)

 

위와같이 최강의 자료형인 String 을 3개나 받는 메소드가있을때
name 과 address 의 순서를 틀리거나 잘못넣거나 하는 실수가 쉽게 발생한다.
 
쉽게 발생하지만 문제가 생겼을때 원인을 알기 정말 힘든 실수다.
이러한 문제는 value object 와 함께라면 해결가능하다.

 

void execute(Naem name, Address address, Phone phone)

 

마무리

value object 를 만드는건 참 간단하다
 
도메인을 나타내는 이름이며 수정자가 없고 equals, hash code 를 재정의하여
파란볼펜1과 파란볼펜2 가 같은거라고 알려주며
볼펜에 잉크가 아닌 연필심이 들어오면 볼팬이 안만들어지게 하면된다.
 
value object 를 사용하여 primitive obsession 가 아닌
value object obsession 가 되자
 
 
참고
https://medium.com/@nicolopigna/value-objects-like-a-pro-f1bfc1548c72
https://enterprisecraftsmanship.com/posts/functional-c-primitive-obsession/