스터디

DTO, VO, Entity 차이

멩주 2022. 10. 22. 17:28

DTO(Data Transfer Object)

  • DTO(Data Transfer Object)로서 계층 간 데이터 교환을 위해 사용하는 객체
  • 계층간 통신에 사용
  • Controller ↔ Service ↔ Repository
  • 데이터 교환을 위해 사용하며 로직을 갖지 않는 순수한 데이터 객체이며 Getter/Setter 메소드만을 갖는다.
package com.study.DTO;

public class MemberDTO {
    private String name;
    private String age;

    public MemberDTO(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

 

VO(Value Object)

  • VO(Value Object)는 값 그 자체를 표현하는 객체
  • 특정한 값을 나타내는 객체
  • 로직을 포함할 수 있으며, 객체의 불변성을 보장합니다.
  • 서로 다른 이름을 갖는 VO 인스턴스더라도 같은 속성값을 갖는다면 같은 객체라고 판단할 수 있다.
    • 이를 위해 equals와 hashCode를 오버라이딩해야 합니다.
  • Equals와 HashCode
public class ColorVO {
    private final double red;
    private final double green;
    private final double blue;

    public ColorVO(double red, double green, double blue) {
        this.red = red;
        this.green = green;
        this.blue = blue;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ColorVO colorVO = (ColorVO) o;
        return Double.compare(colorVO.red, red) == 0 && Double.compare(colorVO.green, green) == 0 && Double.compare(colorVO.blue, blue) == 0;
    }

    @Override
    public int hashCode() {
        return Objects.hash(red, green, blue);
    }
}

오버라이딩 안한 경우
오버라이딩 한 경우

 

 

✔️ DTO를 VO처럼 불변 객체로 사용하면 얻을 수 있는 이점

  • DTO가 전송하고자하는 데이터가 전송 과정 중 변조되지 않았음을 보장할 수 있다.

 

Entity

  • 실제 DB의 테이블과 매칭되는 객체
  • id를 통해 각각의 Entity를 구분
    • 속성값으로 구분되지 않는다.
  • VO와 마찬가지로 로직을 가질 수 있습니다.
@Entity
@Table(uniqueConstraints = {@UniqueConstraint(name = "userNick_unique", columnNames = {"userEmail", "userNick"})})
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int userNo;

    @Column(nullable = false)
    private String userEmail;

    @Column(nullable = false)
    private String userPwd;

    @Column(nullable = false)
    private String userNick;

    @Column(columnDefinition = "varchar(20) default 'ROLE_USER'")
    @Enumerated(EnumType.STRING)
    private UserAuthType userAuth = UserAuthType.ROLE_USER;
}

 

✔️ Entity를 DTO 대신 사용할 수 있지 않을까?

  • 사용할 수는 있지만
  • View에서 표현하는 속성 값이 요청에 따라 달라질 수 있는데, 그때마다 Entity의 속성값을 변경하면 영속성 모델을 표현한 Entity의 순수성이 모호해진다.
  • Controller에서 쓸 DTO와 Entity는 구분하는 것이 좋다.

 

정리

  DTO VO Entity
역할 계층간 데이터 전송 의미있는 값 표현 DB와 매핑되는 클래스
변동 O X (불변성) O
로직 X O(포함할 수 있다) O(포함할 수 있다)

이 글을 참고했습니다