본문 바로가기

개발 개념

VO(Value Object)

1. VO?

객체 지향 프로그래밍에서 자주 사용하는 설계. 값을 표현하기 위해 사용되는 객체로, 불변성을 가진다.

 

2. VO vs DTO

구분 VO(Value Object) DTO(Data Transfer Object)
목적 도메인 값을 표현, 불변 객체로 데이터의 의미를 부여 데이터를 계층 간에 전달하기 위한 객체(Response 용도)
특징 불변성, 값 동등성 비교 가변성을 가질 수 있음(Setter)
사용 위치 주로 도메인 모델 서비스/컨트롤러 계층 간 데이터 전송

 

3. 특징

1.equals & hash code 메서드를 재정의

값이 동일한 두 개의 객체를 생성하고

public class Animal {
	private String animalName;
	
    public Animal(String animalName) {
    	this.animalName = animalName;
    }
}

@Test
void equals() {
    Animal animal1 = new Animal("사자");
    Animal animal2 = new Animal("사자");
    
    assertThat(animal1 == animal2).isFalse();
}

 

Animal 객체를 동일한 이름으로 생성하였다. 이 둘을 비교하면 서로 다른 객체로 구별된다. 이유는 각각의 객체는 참조하고 있는 메모리 주소값이 다르기 때문이다. 따라서 객체가 포함하고 있는 속성값들을 기준으로 비교하기 위해서는 equals 메서드를 재정의하여야 한다.

 

  • VO는 값이 같으면 객체도 같다고 간주합니다.
  • 예를 들어, 두 VO 객체의 메모리 주소가 다르더라도 값이 동일하면 동등하다고 판단합니다.
  • 이를 위해 equals()와 hashCode()를 재정의합니다.

2. 수정자(setter)가 없는 불변 객체

객체를 하나 생성한다.

public class Animal {
	private String animalName;
	
    public Animal(String animalName) {
    	this.animalName = animalName;
    }
    ...getter...
}

public static void main(string[] args) {
    Animal animal1 = new Animal("사자");
    Animal animal2 = animal1;
    animal2.setAnimalName("호랑이");
    // 호랑이
    System.out.println(animal1.getAnimalName());
    // 호랑이
    System.out.println(animal2.getAnimalName());
}

 

 

분명 두 번째로 생성한 객체의 animalName을 변경해 주었는데 첫 번째 객체의 animalName 또한 변경되었다. 왜 그럴까? 앞서 말했듯이 객체는 생성될 때 특정 메모리 주소를 참조한다고 했다. 하지만, animal2 객체를 생성할 때 animal1의 객체의 메모리 주소를 복사하였기 때문에 같은 메모리를 참조하고 있는 두 개의 객체 모두 변경되는 것이다.

이를 해결하기 위해선 setter 없이 객체를 생성하고 수정해야 한다.

public class Animal {
	private String animalName;
	
    public Animal(String animalName) {
    	this.animalName = animalName;
    }
    ...getter...
}

public static void main(string[] args) {
    Animal animal1 = new Animal("사자");
    Animal animal2 = new Animal("사자");
    animal2 = new Animal("호랑이");
    // 사자
    System.out.println(animal1.getAnimalName());
    // 호랑이
    System.out.println(animal2.getAnimalName());
}

객체의 속성 변경이 생긴다면 생성자를 통해 객체를 새로 생성하고 재할당해주어야 한다.

  • VO는 값 자체를 나타내기 때문에 변경할 수 없는 상태를 유지합니다.
  • 값이 바뀌어야 한다면 새로운 VO 객체를 생성합니다.
  • 모든 필드는 final로 선언하고, Setter 메서드를 제공하지 않는 경우가 많습니다.

 

4. 이점

 

  • 코드 가독성 향상: VO를 통해 데이터의 의미를 명확히 표현할 수 있습니다.
  • 데이터 무결성 보장: 불변성을 통해 데이터를 변경할 수 없으므로 안정성이 높아집니다.
  • 객체지향적인 설계: 값과 행위를 묶어 객체로 관리하여 코드의 재사용성을 높입니다.

 

 

5. 활용

  • 도메인 모델링: 값 자체에 의미를 부여하고, 유효성 검사와 관련 동작을 묶어서 표현할 때.
  • 의미 있는 값 표현: 금액, 날짜, 좌표 등 단순 원시값을 객체로 포장해 사용하는 경우.
  • 애플리케이션 내 데이터 관리: 여러 속성을 가진 데이터를 묶어 전달할 때.

 

 

출처: https://tecoble.techcourse.co.kr/post/2020-06-11-value-object/

 

'개발 개념' 카테고리의 다른 글

단위 테스트와 테스트 더블  (0) 2025.02.13
클린아키텍처  (0) 2025.02.11
객체지향 생활 체조 원칙 9가지  (0) 2025.02.11
1급 컬렉션  (1) 2025.02.11
객체지향  (4) 2025.02.07