DTO vs VO 개념정리

dO_the_Jeegu·2023년 3월 26일
0

개념정리

목록 보기
2/5

✔ 참고영상
[10분 테코톡] 🎼라흐의 DTO vs VO
[10분 테코톡] 📍인비의 DTO vs VO


DTO (Data Transfer Object)

: 데이터 전송 객체

그림 출처
  • 로직을 갖고 있지 않는 순수한 데이터 객체
    *getter/setter 메서드만 가짐

  • 계층(Layer) 간 데이터 교환을 위해 사용하는 객체
    *계층? View, Controller, Service, DAO 등

DTO : 데이터를 전송할 때 사용하는 바구니


<DTO - 예시1>

public class ProductDTO {
    private String name;
    private double price;

    public String getName() {
        return name;
    }

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

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
(참고 : Chat GPT)

여기서 <예시 1>의 ProductDTOSetter를 사용하기 때문에 데이터가 가변적이라고 할 수 있다.

그러나 DTO의 주목적은 데이터 전송이므로 데이터의 불변성(Immutability)을 지키는 것이 좋다. 이를 위해 개발자들은 일반적으로 아래와 같은 규칙을 따른다.

  1. 데이터를 설정할 때 생성자와 초기화 메서드 사용
  2. 필드 변수에 final 키워드 추가
  3. Setter 메서드 삭제

위 세가지 규칙을 따라 수정한 코드는 다음과 같다.

<DTO - 예시2>

public final class ProductDTO {
    private final String name;
    private final double price;

    public ProductDTO(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}
(참고 : Chat GPT)

VO (Value Object)

: 값 객체

  • 값 그 자체를 표현하는 객체. 의미 있는 값을 표현할 때 사용
  • 객체의 불변성 보장
  • 로직 포함 가능
  • 서로 다른 이름을 가진 VO 인스턴스의 모든 속성 값이 같다면 같은 객체로 판단

ex1) ColorVO라는 VO가 있을 때 RCB값이 color1(255, 0, 0), color2(255,0,0) 속성을 가지면 color1과 color2는 이름이 다르더라도 같은 객체로 판단

ex2) 만원짜리 지폐의 고유 번호가 다르다고 해서 각각의 지폐를 다른 지폐라고 생각하지 않고 똑같은 만원 지폐로 판단


<VO - 예시1>

public class ColorVO {
    private int r;
    private int g;
    private int b;

    public ColorVO(int r, int g, int b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }

    public double getBrightness() { //밝기 값을 계산하는 로직
        return Math.sqrt(0.299 * r * r + 0.587 * g * g + 0.114 * b * b);
    }
}
(참고 : Chat GPT)

앞서 ‘서로 다른 이름을 가진 VO 인스턴스의 모든 속성 값이 같다면 같은 객체로 판단’한다고 하였는데, 이는 어디까지나 규칙일 뿐, 실제로 구현하는 것은 개발자의 몫이다.

기본적으로 Java에서 equals()hashCode() 메소드는 객체의 주소값을 비교하기 때문에, 만일 <예시 3> 코드 그대로 Test를 돌린다면 객체의 값이 같더라도 다른 객체로 취급되어 두 메서드 모두 실패했다고 뜰 것이다.

그림 출처

따라서 개발자들은 위 그림과 같이 equals()hashcode() 메서드를 오버라이딩하여 해당 기능을 구현해야 한다.

오버라이딩을 적용한 코드는 다음과 같다.

<VO - 예시2>

public class ColorVO {
    private int r;
    private int g;
    private int b;

    public ColorVO(int r, int g, int b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }

    public double getBrightness() {
        return Math.sqrt(0.299 * r * r + 0.587 * g * g + 0.114 * b * b);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof ColorVO)) return false;
        ColorVO colorVO = (ColorVO) o;
        return r == colorVO.r && g == colorVO.g && b == colorVO.b;
    }

    @Override
    public int hashCode() {
        return Objects.hash(r, g, b);
    }
}
(참고 : Chat GPT)

✍정리

DTOVO
사용목적계층(layer) 간 데이터 전송도메인 객체의 값을 나타내고 유지
로직유무없음
Getter/Setter만 존재
비즈니스 로직 존재
가변성Setter가 있는 경우 가변
Setter가 없는 경우 불변
불변
profile
오지는 갓생 살기

2개의 댓글

comment-user-thumbnail
2023년 3월 27일

퍼가요~

1개의 답글