해당 포스팅은 테코톡 유튜브를 기반으로 작성되었습니다.
http://https://www.youtube.com/watch?v=z5fUkck_RZM
DTO와 VO의 혼용 사례와 원인
구글링을 해보면 일반적으로 많은 사람들이 DTO와 VO를 혼용하여 사용하고 있습니다.
J2EE Patterns라는 책의 초판에서는 데이터 전달용 객체를 VO로 정의하였지만
혼동의 여지가 있다고 판단하여 2편에서는 데이터 전달용 객체를 TO로 재정의하면서
사람들이 혼용하게 되었을것이라고 여겨집니다.
현재 데이터 전달용 객체의 정의는 TO앞에 데이터를 의미하는 D를붙인
DTO로 통용되고 있습니다.
DTO와 VO는 이름부터 다른만큼 구분하여 사용하여야 합니다.
https://book.naver.com/bookdb/book_detail.nhn?bid=222463
https://book.naver.com/bookdb/book_detail.nhn?bid=267275
결론먼저
DTO = 데이터 전달용
VO = 값 표현용
DTO란?
DTO(Data Transfer Object)
데이터를 전달하기 위해 사용하는 객체
데이터를 담아서 전달하는 바구니라고 생각하면 이해하기 쉽습니다.
구체적으로는 '계층 간' 데이터를 전달하기 위한 객체라고 표현합니다.
DTO의 특징
- 오직 getter / setter 메서드 만을 갖는다.
- 다른 로직을 갖지 않는다.
보내는쪽에서 setter를 사용하여 데이터를 DTO를 사용해서 보내고
받는쪽에서 getter를 사용해 데이터를 꺼내는 방식입니다.
DTO를 불변객체로
setter 메서드를 가질 경우 해당 DTO의 데이터는 가변적이게 됩니다.
하지만 setter 메서드를 삭제하고 생성자를 통하여 속성값들을 초기화하게 만들어
불변객체로 만든다면 전달과정 도중에 변경되지 않음을 보장할 수 있습니다.
결론적으로 불변객체로 사용한다면 안정적으로 사용이 가능합니다.
DTO Class와 Entity Class를 분리하자
Entity클래스는 절대로 요청이나 응답값을 전달하는 클래스로 사용하면 안됩니다.
Entity클래스는 데이터베이스와 매핑되어있는 핵심 클래스이기 때문입니다.
Entity클래스를 기준으로 테이블이 생성되고 스키마가 변경됩니다.
View는 비지니스 요구사항에서 자주 변경되는 부분입니다.
만약 Entity 클래스를 요청이나 응답값을 전달하는 용도로 사용한다면
View가 변경될 때 마다 Entity클래스를 그에맞춰서 매번 같이 변경해야 합니다.
수많은 서비스 클래스나 비지니스 로직들이 Entity클래스를 기준으로 동작합니다.
Entity클래스를 변경하면 관련되어 있는 무수히 많은 클래스에 영향을 끼칩니다.
따라서 요청이나 응답값을 전달하는 클래스로는 반드시 View 변경에 따라
다른 클래스들에게 영향을 끼치지않고 자유롭게 변경할 수 있는 DTO를 사용하여야 합니다.
또한, 응답값으로 여러 테이블들을 조인한 결과값을 조회할 경우가 빈번하기 때문에
Entity클래스 만으로는 응답값을 표현하기 어려운 경우가 많습니다.
그래서 Entity와 결과값을 전달해주는 DTO는 꼭 분리하여 사용해야 합니다.
VO란?
VO(Value Object)
값 그자체를 표현하는 객체
ex) 실생활의 VO 예시 - 돈
각각의 지폐에는 고유번호가 존재합니다.
하지만 우리는 만원짜리 지폐의 고유번호가 다르다고 해서
다른 만원이라고 하지 않고 같은 만원이라고 부릅니다.
이렇게 값 그자체만을 나타내고 값으로만 비교되는 객체를 VO라고 합니다.
지폐의 고유번호를 각 객체의 주소라고 생각하면 됩니다.
Money VO 클래스
VO는 값 자체를 표현하기 때문에 불변객체여야 합니다.
따라서 보시는것처럼 setter성격의 메소드는 포함하면 안되고
생성자를 통해서만 값을 초기화해야 합니다.
아래를 보면 getHalfValue라는 로직을 포함하고 있습니다.
DTO가 getter / setter 외의 로직을 포함할 수 없는것과는 달리
VO는 이처럼 이외의 로직을 포함할 수 있습니다.
일반적인 객체는 기본적으로 equals 비교와 hashCode 비교가 모두 불일치로 나옵니다.
HashXXX (HashSet, HashMap, Hashtable)의 동등 비교방식
완전한 VO를 만들기 위해서는
객체를 속성값들로만 비교하도록 equals 메소드와 hashcode 메소드를
모두 오버라이딩 해주어야 합니다.
이전에 equals 비교와 hashCode 비교시 실패했던 테스트를 다시 실행해보면
모두 통과하는 결과를 볼 수 있습니다.
이로써 money객체가 완전한 VO가 되었음을 알 수 있습니다.
마지막 정리 DTO vs VO
'프로젝트 > 프로젝트 관련' 카테고리의 다른 글
Docker란 무엇인가? 왜 쓰는가? 소개편 (0) | 2021.12.25 |
---|---|
JDBC, SQL Mapper(MyBatis), ORM (0) | 2021.12.25 |
부하 분산을 위한 MySQL 쿼리요청 분기 (0) | 2021.12.14 |
Disk Based Database, In Memory Database (0) | 2021.12.13 |
Sticky Session, Session Clustering, Session Storage (0) | 2021.12.13 |