들어가며
VO란 값 객체로만 알고 있었다. 값을 가진 무언가? 라는 개념으로 이해했는데 이에 대해 조금 더 자세히 알고 싶어서 정리해보게 되었다.
VO란 ?
VO란 값을 가지는 객체. 즉 값 자체로 의미를 갖는 객체이다.
- 속성 값이 모두 같으면 객체이다.
- 불변이다.
VO를 사용하는 이유
원시값 타입이 도메인 객체를 모델링 하기에 충분하지 않기에 사용한다. 도메인에서 의미있는 값으로 VO를 묶어서 사용해야 한다.
여기서 든 의문은 원시값 포장과 다른점이 뭐지? 라는 것이였다.
VO 의 필수조건은 먼저
- equals & hashCode 메서드를 재정의
- 수정할 수 없는 불변
이다.
그러므로 변수를 수정하는 로직이 있다면 이는 VO가 아니다.
원시 타입의 기능을 사용하지 않기에 VO를 사용한다.
private final String name;
public Player(String name) {
this.name = name;
}
Player의 이름 name을 String타입으로 선언하였다.
하지만 String은 name이 가지지 않는 속성과 연산들을 가지고 있는데 예를 들자면
- 이름을 연결한다.
- 이름을 모두 소문자, 모두 대문자로 변경한다 등등
Name은 기본 String이 아니기 때문에 위와 같은 방식으로 사용할 필요가 없다!
이름은 결국 String 타입이지만 String 타입의 메서드들을 사용하지 않고,
이렇게 잘못된 원시값을 사용하는 것을 primitive obsession 이라고 한다.
검증
내가 이름에 대한 검증을 하고 싶다면
private void validNameLength(String name) {
if (name.length() > MAX_LENGTH) {
throw new IllegalArgumentException(INVALID_NAME_LENGTH_MESSAGE);
}
}
이런 코드를 작성할 수 있을 것이다.
만약 여러 곳에서 똑같은 name을 사용하고자 한다면 이런 검증 로직이 여러개 여야한다. 하지만 Name값을 포장하여 생성자에서 검증을 한다면 중복을 없애고 검증할 수 있다.
Value Object 기본 특성
Immutability (수정자가 없다)
Value Object는 불변이다.
Setter를 통해 한번 생성 후 값을 변경할 수 없음을 의미한다. 그래서 VO는 항상 호출 시 값 변경이 없다.
Value equality (값 동등성)
여러 VO들이 주소값이 모두 다르더라도 값이 같으면 동등한 객체로 판단된다.
따라서 equals & hashcode를 재정의해야한다.
Self validation (자가 유효성 검사)
위에서도 말했지만 생성자가 주입될 때 값의 유효성 검사를 진행할 수 있다. 그래서 모든 유효성 검사는 생성 시간에 이루어진다.
'코코코딩공부 > JAVA' 카테고리의 다른 글
[JAVA] 캐싱 (0) | 2023.03.19 |
---|---|
[JAVA] 상속 과 조합 (0) | 2023.03.13 |
[JAVA] 제네릭 Generic (1) | 2023.03.04 |
[JAVA] 예외 처리 (0) | 2023.02.26 |
[JAVA] 일급 컬렉션 (0) | 2023.02.25 |