DTO, VO 차이 한 번에 이해하기!
해당 내용은 잘못된 부분이 있을 수 있다.
너무 신뢰하지는 말아줬으면 좋겠다.
소프트웨어 개발에서 VO(Value Object)와 DTO(Data Transfer Object)는 중요한 개념이다.
이 두 가지 개념은 객체 지향 프로그래밍에서 데이터를 표현하고 전달하는 데 자주 사용되지만, 그 목적과 사용 방법에는 큰 차이가 있다.
이 글을 통해서 그동안 헷갈렸던 VO와 DTO의 차이점에 대해 자세히 알고 갔으면 좋겠다.
VO(Value Object)란?
VO(Value Object)는 불변(Immutable) 객체로, 특정 개념을 표현하기 위해 사용된다.
주로 동등성(equality) 이 중요한 경우 사용되며, 두 VO 객체가 같은 값을 가진다면 동일하다고 간주한다.
불변성을 통해 객체가 변경될 수 없으므로, 데이터를 안전하게 보호할 수 있으며, 멀티스레드 환경에서도 안전하게 사용할 수 있다.
오로지 데이터를 읽기(read-only)위해 getter만 갖는 사진과 같은 개념이다.
우리는 사진을 오로지 읽고 데이터를 수집하기 바쁘다. 사진을 수정하려고 원본 사진에 무엇을 하진 않는다.
VO는 마치 원본 파일이 절대 수정되지 않는 것처럼, 한 번 설정된 값을 절대 변경하지 않는다.
대신 새로운 값을 가지는 새로운 객체를 생성해야 한다.
VO의 장단점
장점:
불변성:
VO는 불변 객체로 설계되어 있어, 데이터의 일관성을 유지할 수 있습니다. 상태가 한 번 설정되면 변경되지 않기 때문에 안정성이 높습니다.동등성 비교:
VO는 값을 기준으로 동등성을 비교할 수 있습니다. 두 객체가 같은 값을 가지고 있다면, 동일한 객체로 간주합니다.도메인 로직 포함 가능:
VO는 도메인 로직을 포함할 수 있어, 해당 객체가 도메인 모델에서 의미 있는 역할을 할 수 있습니다.
도메인 로직이 멀까
자신이 갖고 있는데 데이터를 기반으로 기존 데이터를 검증하거나 다른 vo와 동등성을 비교하는일을 할 수 있는 로직이란다.
단점:
재사용의 어려움:
VO는 불변성이 강제되기 때문에, 값이 변경될 때마다 새로운 객체를 생성해야 합니다. 이런 특성 때문에 자주 변경되는 데이터에는 다소 비효율적일 수 있습니다.복잡성:
VO를 설계할 때는 다양한 값 객체를 정의해야 하므로, 코드가 복잡해질 수 있습니다.
VO 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class Money {
private final int amount;
private final String currency;
// 생성자에서 값을 검증하고 초기화합니다.
public Money(int amount, String currency) {
if (amount < 0) {
throw new IllegalArgumentException("Amount cannot be negative");
}
if (currency == null || currency.isEmpty()) {
throw new IllegalArgumentException("Currency cannot be null or empty");
}
this.amount = amount;
this.currency = currency;
}
// 두 Money 객체의 값을 비교하여 동등성을 판단합니다.
//VO는 동등성 비교를 위해 equals와 hashCode 메서드를 오버라이드합니다.
//이는 두 VO 객체가 동일한 값을 가질 때 동일한 객체로 간주되도록 합니다.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Money money = (Money) o;
return amount == money.amount && currency.equals(money.currency);
}
@Override
public int hashCode() {
return Objects.hash(amount, currency);
}
// 금액을 더하는 도메인 로직
//이 메서드는 두 Money 객체를 더해 새로운 Money 객체를 반환합니다.
//이처럼 VO는 불변성을 유지하며, 값이 변경되었을 때 항상 새로운 객체를 생성합니다.
public Money add(Money other) {
if (!this.currency.equals(other.currency)) {
throw new IllegalArgumentException("Currencies must match to add amounts");
}
return new Money(this.amount + other.amount, this.currency);
}
public int getAmount() {
return amount;
}
public String getCurrency() {
return currency;
}
}
DTO(Data Transfer Object)란?
무엇을 이미지 해야 외우기 쉬울까?
해당 개념의 역할에 집중해보자. 데이터 전송과 캡슐화다.
특정 계층 간 데이터를 캡슐화하여 전달한다.
DTO는 데이터 전송 외에는 별다른 기능을 가지지 않으며,
(getter 와 setter를 제외한) 로직이 포함되지 않는 것이 일반적이다.
DTO는 객체 사이의 의존성을 줄이면서 데이터를 안전하게 전달하기 위해 사용된다.
이를 통해 데이터의 구조가 변경되더라도, 다른 계층에 영향을 주지 않고 데이터를 전송할 수 있다.
이 개념은 일종의 보고서이다. 데이터를 넘겨주는 쪽이나 데이터를 받는 쪽이다. 같은 클래스의 데이터를 받을 것이다. 그렇다면
서식이 정해져있는 일종의 잠금장치가 있는 보고서라고 볼 수 있다.
DTO의 장단점
장점:
데이터 전송 최적화:
DTO는 데이터 전송에 최적화되어 있어, 전송 과정에서 불필요한 데이터를 줄일 수 있습니다.캡슐화:
DTO는 데이터를 캡슐화하여 계층 간의 의존성을 줄이고, 데이터 전송에 집중할 수 있습니다.유연성:
DTO는 데이터를 단순화하거나 매핑하는 데 유연하게 사용할 수 있습니다. 다양한 계층 간 데이터를 주고받을 때 유용합니다.
단점:
로직의 부재:
DTO는 데이터 전송에만 집중하기 때문에, 비즈니스 로직이 포함되지 않습니다. 이로 인해 객체가 자율성을 잃을 수 있습니다.불변성 부족:
DTO는 일반적으로 가변 객체로 설계되기 때문에, 데이터의 일관성이 깨질 수 있는 위험이 있습니다.
DTO (Data Transfer Object) 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class UserDTO {
private String username;
private String email;
private String phoneNumber;
public UserDTO() {
}
public UserDTO(String username, String email, String phoneNumber) {
this.username = username;
this.email = email;
this.phoneNumber = phoneNumber;
}
// Getter와 Setter만 포함되어 있으며, 데이터 전송만을 목적으로 합니다.
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
VO와 DTO의 차이점 정리
- 사용 목적:
- VO는 특정 값을 표현하고, 값의 동등성을 확인하기 위해 사용된다.
- DTO는 데이터 전송을 위해 사용된다.
- 불변성(Immutable) vs 가변성(Mutable):
- VO는 불변성이 강제되며, 생성 후 값이 절대로 변경되지 않는다.
- DTO는 가변성으로 인해 데이터를 자유롭게 수정할 수 있다.
- 도메인 로직:
- VO는 도메인 로직을 포함할 수 있다.
- DTO는 데이터를 전송하는 역할만 하며, 로직을 포함하지 않는다.
결론
VO와 DTO는 각각 다른 목적을 위해 설계된 객체이다.
VO는 값의 동등성 및 불변성을 중시하며, 도메인 로직을 포함할 수 있는 반면, DTO는 데이터 전달을 위한 가벼운 객체로서 로직이 포함되지 않는다.
각 개념의 특성을 잘 이해하고, 상황에 맞게 적절히 사용해야 한다.
출처
- https://www.inflearn.com/community/questions/1166348/dto-%EA%B4%80%EB%A0%A8-%EC%A7%88%EB%AC%B8%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4
- https://www.youtube.com/watch?v=J_Dr6R0Ov8E
- https://velog.io/@chosj1526/VO-DAO-DTO-ENTITY%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%9E%A5%EB%8B%A8%EC%A0%90-%EB%B0%8F-%EC%B0%A8%EC%9D%B4
- https://maenco.tistory.com/entry/Java-DTO%EC%99%80-VO%EC%9D%98-%EC%B0%A8%EC%9D%B4
- https://youwjune.tistory.com/39