프로그래밍/개발 지식

[개발 지식] Entity vs DTO vs VO

I'm_ 2024. 1. 16. 14:25

✅들어가며

도메인 중심 설계를 포스팅하면서 공부했을 때, 데이터 중심 개발은 getter와 setter사용으로 캡슐화가 되지 않는 점을 단점으로 꼽으면서 도메인 중심 개발이 이를 보완할 수 있다고 하였다.

그런데 나는 배달 어플 프로젝트를 시작하며 객체 생성을 위한 클래스를 만들면서 Getter와 Setter를 이용하였다. (이 방법dl 이 아닌 다른 방법으로 클래스를 만들어 본 적이 없기도 하다;;)
그렇다면 도메인 중심 개발에서 클래스를 만들기 위해서는 어떻게 해야할까? 이를 알아보기 위해 Entity, DTO, VO에 대해 정리해 보았다.

✅DTO(Data Transfer Object)

  • 계층(Layer) 간 데이터를 서로 주고받을 때 사용하는 객체이다.
  • 로직을 가지고 있지 않으며, getter와 setter만 가지고 있다.

아래는 프로젝트를 위해 만든 클래스인데 오늘 공부해보니 DTO로 만든 것을 알 수 있다.

package Food;

public class Food {
    private String name;
    private int price;
    private String description;

    public String getName() {
        return name;
    }

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

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

✅VO(Value Object)

  • 값을 나타내는 객체이다.
  • 개념적으로 완전한 하나를 표현한다. 예를 들어 우편번호, 도로명주소, 상세주소의 데이터를 주소라는 하나의 개념(VO)으로 표현할 수 있다.
  • 로직을 포함할 수 있다.
  • 데이터 변경 기능을 제공하지 않는 불변 객체이다. Getter만 가질 수 있고, 값은 생성자를 통해서 설정할 수 있다.
  • 서로 다른 이름을 갖는 VO 인스턴스라도 모든 속성 값이 같다면 같은 객체로 판단된다. 이를 위해 Object 클래스의 equals()와 hashcode() 메서드를 오버라이딩 해야한다. (IntelliJ의 Generate기능 사용)
package Food;

import java.util.Objects;

public class Food {
    private String name;
    private int price;
    private String description;

    public Food (String name, int price, String description) {
        this.name = name;
        this.price = price;
        this.description = description;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Food food = (Food) o;
        return price == food.price && Objects.equals(name, food.name) && Objects.equals(description, food.description);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, price, description);
    }
}

✅Entity

  • DB의 테이블과 매핑되는 객체로, 주로 데이터베이스에 저장되고 관리된다.
  • 로직을 가질 수 있으며, 식별자를 가진다.
❗식별자 생성 방법
- 특정 규칙에 따라 생성
- UUID나 Nano ID와 같은 고유 식별자 생성기 사용
- 값을 직접 입력
- 일련번호 사용(시퀀스나 DB의 자동 증가 칼럼 사용)

 

기존 DTO로 만들었던 Food 클래스를 Entity로 바꿔보았다.

공부할 떄 참고한 JPA를 사용한 Entity 예제 코드를 보면 @Entity, @Id 등의 어노테이션을 사용하고 있다.

하지만 나는 아직 JPA를 사용하거나 공부해보지 않아서 우선 내가 이해한 대로 식별자를 추가하여 Entity 클래스를 만들었다. 이 부분은 앞으로 공부한 후 적용해 나가야겠다.

package Food;

import java.util.UUID;

public class Food {
    private String id;
    private String name;
    private int price;
    private String description;

    public Food (String name, int price, String description) {
        this.id = this.createId();
        this.name = name;
        this.price = price;
        this.description = description;
    }

    private String createId(){
        UUID uuid = UUID.randomUUID();
        return uuid.toString();
    }
}

 

 

출처 : https://www.devkuma.com/docs/dto-vo-entity/

✅나가며

이전에 프로젝트를 진행할 때는 큰 생각 없이 무작정 따라 만들었는데 스진초를 진행할 수록 코드에 대한 이해와 '왜'에 대한 고민을 하게 된다. 남은 프로젝트도 지금처럼 잘 마무리 해야겠다!

 


📚참고 자료