VO vs DTO vs Map

YeopKing·2022년 3월 10일

VO 와 Map의 차이는 ?

언제 VO를 쓰고 언제 Map를 써야하는가?

Java Beans

  • 일반적으로 자바빈은 속성과, 그 속성에 대한 getter,setter 메서드로 구성된 데이터 객체 (VO,Value Object)를 말하며 데이터 전송에 사용되는 객체를 말한다.
  • 자바로 작성된 재사용 가능한 소프트웨어 컴포넌트
  • getter,setter 메서드를 통해 컴포넌트에 접근가능

VO(Value Object)

  • 데이터 그 자체로 의미 있는 것을 담고 있는 객체
  • DTO와 같은 개념이나 차이점은 Read-Only 속성 객체이다.
  • 간단한 독립체(Entity)를 의미하는 작은 객체를 의미한다.

DTO(Data Transfer Object)

  • 계층 간 데이터 교환을 위한 객체
  • 일반적인 DTO는 로직을 가지고 있지 않다. 순수한 데이터 객체이며 속성과 속성에 접근하기 위한 getter,setter 메서드로만 구성되는 POJO

Map

  • Key와 Value의 쌍으로 값을 저장하는 컬렉션
  • '사람'을 예로 들면 누구든지 "이름" = "김준엽" , "생일" = "9x03x4" 등으로 구분할 수 있다.
    자바의 맵(Map)은 이러한 대응관계를 쉽게 표현할 수 있게 해 주는 자료형이다.

public class Member {
    private Long id;
    private String name;
    private Grade grade;

    public Member(Long id, String name, Grade grade) {
        this.id = id;
        this.name = name;
        this.grade = grade;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Grade getGrade() {
        return grade;
    }

    public void setId(Long id) {
        this.id = id;
    }

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

    public void setGrade(Grade grade) {
        this.grade = grade;
    }
}

VO 작성 시 , getter,setter(Data Access Method)가 왜 필요한 것인지?

VO에 getter,setter를 쓰는 경우

  • 변수에 새로운 값을 할당할 때마다 validation 검사기능

  • lazy loading 가능

  • read와 write 권한 다르게 설정 가능(public,private)

  • getter,setter는 캡슐화(encapsulation)를 구현하는 가장 기본적인 형태이다. 언뜻 보면 그냥 변수를 public으로 선언하여 접근하는 것과 별반 달라 보이지 않는다. 하지만 public으로 선언하여 외부에서 객체의 각 변수에 접근하여 값을 변경하는 경우가 발생할 수 있다.

  • 객체의 상태는 오직 그 객체의 동작에 의해서만 접근/변경되도록 하는 게 맞다. 한 객체가 다른 객체의 필드를 변경하려는 경우, public method를 통해 객체의 상태(필드값)를 변경해야 한다. 또한, 외부에서 접근 가능한 public method는 최소한으로 해야 한다

Q. 캡슐화를 위한 방법으로 getter,setter밖에 없는 걸까?

  • getter,setter 메서드로 접근할 수 있도록 하는 것이 진정한 캡슐화가 맞느냐는 의문들도 많다.
    캡슐화를 위해 사용했다고 하면 getter,setter 말고는 다른 방법이 없는 것인지도 궁금하다.
    또, 데이터 객체에 대한 정보은닉이 항상 필요한가?
    결론부터 이야기하자면 OOP(객체지향 프로그래밍)를 지향한다면 반드시 필요하다.
    (진짜 객체 지향은 정보은닉에서 시작된다.)

    getter,setter가 필요 없는 경우에는 Java의 Lombock의 어노테이션을 사용해서 해결할 수 있다.

Map vs VO

Map 장점

  • select를 사용하는 경우는 보통 2개 이상의 테이블을 조인하여 조회하는 경우가 많아 VO로는 표현이 복잡하여서 Map을 사용한다.

Map 단점

  • Map의 key 또는 value가 null이면 Map의 해당 필드 자체를 key로 가져가지 않는다.
    따라서 쿼리 수행 시, key 값 자체가 존재하지 않아 오류 발생(이 경우를 대비하여 쿼리에 jdbcType 선언 필요, 해당 값이 null일 경우 초기화 타입 지정) 여러 타입을 담아야 하기 때문에 Map은 Value 선언 시 Object로 할 수밖에 없다.
    그러나 Object는 최상위 타입이기 때문에 type이 매치되지 않는 경우가 발생해도 실제로 돌려보지 않는 한 알 수가 없다.
    Object로 선언하여 모든 타입을 담기 때문에, 부가적인 casting 작업이 발생할 수 있다.

VO 장점

  • 비즈니스 로직 상 데이터가 명확해야 하는 경우 VO권장(ex. 정산,공수,산정,매표)
  • 특정 값의 key 또는 value(필수 값인 경우)가 null인 경우 VO 클래스 내에 선언된 타입으로 초기화 수행됨, 쿼리 수행시 null로 인한 오류가 나지 않음
  • 멤버 변수에 대한 구체적인 타입을 선언하기 때문에 타입이 매치되지 않는 경우 컴파일 에러가 발생하여 바로 알아챌 수 있다.
  • 반드시 값이 필요한 변수에 대해 생성자 파라미터로 필요한 값을 넣을 수 있어, 이 값이 없는경우 컴파일 에러가 발생한다.

VO 단점

  • Map에 비해 소스가 많아진다.
  • getter,setter 메서드를 일일이 작성해주어야 하는 번거로움이 있었지만
    현재 Lombock을 사용하여 어노테이션 형태로 조금 더 간편하게 사용 할수있다.(@Getter,@Setter)
profile
좀 더 나은 내일을 위해

0개의 댓글