본문 바로가기

CS지식/Spring

[CS지식 - Spring] DTO와 VO차이

1. DTO(Data Transfer Object)

  • 계층(Layer)간 데이터 교환을 위해 사용하는 객체
    ▶ 로직을 갖지 않고, getter, setter메소드만 갖음
  • 완전히 전달용도로만 사용하기 때문에 getter, setter로직만 필요할 뿐 다른 로직은 필요하지 않음
//getter와setter 메서드 만을 가진다
public class UserDTO {
    
    private String name;
    private String id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
    
}
  • 보내는 쪽에서는 setter를 이용해 값을 담아 전달하고, 받는 쪽에서는 getter를 이용해 값을 꺼내 씀
  • setter의 경우 변조가능성이 있기때문에 생성자로 값을 넣어주면 전달하는 과정에서 변조가 불가능
//생성자를 이용한 불변 객체
public class UserDTO {

    private String name;
    private String id;

    public UserDTO(String name, String id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public String getId() {
        return id;
    }

}

 

2. VO(Value Object)

  • 값 그자체를 표한하는 객체
    ▶로직 포함가능, 불변성(객체의 정보가 변하지않음)을 보장
    ▶불변성 보장을 위해 생성자 사용
//생성자를 이용한 불변 객체
public class CarVO {

    private final String color;

    public CarVO(String color) {
        this.color = color;
    }
    
}

자동차의 색깔의 값을 가지고 있는 vo를 만들어 객체 두개를 비교 테스트함

class CarVOTest {

    @Test
    void CarVOEqualTest() {
        final String color = "red";

        CarVO car1 = new CarVO(color);
        CarVO car2 = new CarVO(color);

        assertThat(car1).isEqualTo(car2);
        assertThat(car1).hasSameHashCodeAs(car2);

    }

}
  • 객체의 주소값을 비교하기때문에 같은 것과는 상관없이 테스트에서 에러남
  • 서로 다른 이름을 갖는 vo인스턴스라도 모든 속성 값이 같다면 두 인스턴스는 같은 객체라고 할 수 있음
    ▶ VO에는 Objext클래스의 equals()와 hasCode()를 오버라이딩 해야함
public class CarVO {

    private final String color;

    public CarVO(String color) {
        this.color = color;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CarVO carVO = (CarVO) o;
        return Objects.equals(color, carVO.color);
    }

    @Override
    public int hashCode() {
        return Objects.hash(color);
    }
}

▶ VO는 값 그 자체를 나타내기 때문에 setter같은 성격의 변조 가능성이 있는 메서드가 존재하면 안되며, 
     두 객체의 필드값이 같다면 모두 같은 객체로 만드는 것이 핵심

 

3. DTO vs VO

 

  DTO VO
목적 계층간 데이터 전달 값 자체 표현
동등성 필드값이 같아도
같은 객체x
필드값이 같으면 같은 객체
가변성 setter존재 시 가변
setter 비존재 시 불가변
불변
로직  getter/ setter 이외
로직x
getter/setter외의
로직있어도 무방