앞서 DDD에 대한 포스트를 작성하며 Domain에 대해서도 살펴보게 되었다.
최근에 Domain이랑 Entity에 대한 차이가 무엇이냐는 질문을 받았는데, 나는 여태껏 거의 동일한 개념이라고 생각해 왔다.
저번 포스트에 이어 이번 포스트에는 Entity가 무엇인지 정리하고, 많은 사람들이 혼용하는 DTO와 VO에 대해서도
함께 정리하려고 한다.
Entity란?
Entity 클래스는 실제 DB의 Relation과 1:1로 매핑되는 클래스로,
DB Relation 내에 존재하는 attribute만 속성(필드)로 가져야 하는 것이 특징이다.
Domain Logic만을 가지고, Presentation Logic(View)를 가져서는 안된다.
가급적 외부에서는 Entity 클래스의 필드에 직접적으로 접근하지 않도록 하고, getter/setter보다 용도에 맞는 구체적인 메서드를 정의하여 값을 사용하도록 하는 것이 권장된다.
당연히 Request나 Response시 Entity 클래스를 직접 사용하는 것은 권장하지 않는다.
DTO란?
DTO(Data Transfer Object)란, 데이터 전송 객체의 준말이다.
계층 간 데이터 교환을 위해 사용하고,
(ex. View <-(DTO) -> Controller <- (DTO) -> Service )
별도의 로직 없이 getter/setter만 존재한다.
DTO는 주로 비동기 처리를 위해 사용한다.
public class PersonDTO {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
getter와 setter에서 중요한 것은 Property 개념이지만, Java에서는 Property 개념을 별도로 제공하지 않는다.
하지만 Java에서 프로퍼티라는 개념을 사용하기 위해 다음과 같은 약속을 하게 된다.
-> set,get 뒤에 나오는 단어가 property임을 약속하자
위 클래스에서는 프로퍼티가 name, age이다. PersonDTO에서 name, age의 Key 값으로 들어온 데이터는 리플렉션 기법으로 setter를 실행시켜 데이터를 저장할 수 있게 된다.
이러한 제어 과정의 주도권은 프레임워크에게 있다는 것에 주목하자.
View에 있는 form에서 name 필드 값을 프로퍼티에 맞추어 넘긴다면, 이를 전달받는 곳에서는 일일히 처리하는 것이 아닌,
name 속성의 이름이랑 매칭되는 Property에 자동으로 DTO가 인스턴스화되어 PersonDTO를 Type으로 하는 값을 전달받을 수 있다.
왜 Entity가 있는데 DTO를 따로 만들어서 쓰지?
그 이유는 DB(Persistence Layer)와 View(Presentation Layer)의 명확한 분리를 위해서이다.
Entity는 테이블과 매핑되므로, 변경되면 다른 클래스에 영향을 끼치기 쉽다.
또한, DTO는 주로 View와 통신하며 자주 변경되므로 분리가 필요하다.
DTO는 도메인 모델 객체인 Entity를 복사한 후, Presentation Logic만을 추가할 뿐이다.
VO란?
VO(Value Object)는 값 객체의 의미를 가진다. 특정 비즈니스 값을 담아낸다.
언뜻 보면 DTO와 비슷하지만, Read Only 속성을 가진다.
모든 속성 값이 같다면 같은 객체임을 의미한다.
생성자를 제외하고 set 성격의 메서드를 사용할 수 없다.
VO 내부에 선언된 필드 내 모든 값들이 같은 경우, 동일한 객체라고 판단한다.
이를 위해 equals()와 hashCode() 메서드를 Override해서 각 객체의 동일성을 판별할 수 있다.
음.. 그래서 DTO랑 VO는 무슨 차이야?
정리하자면, DTO는 값을 전달하는 것이 주 목적이고
VO는 값을 표현하는 것이 목적이다.
(외부 시스템과 데이터 통신을 할 경우 DTO로, DB에서 가져오는 Data는 VO로 정의 후 사용)
그리고, DTO는 속성 값이 같아도 서로 다른 객체라고 판단하지만, VO는 같은 객체로 취급한다.
마지막으로, DTO는 값의 전달이 그 목적이기 때문에 getter/setter를 사용할 수 있지만,
VO는 불변성을 보장하기 위해 setter를 사용하지 못한다.
그러나 VO에서는 setter를 제외한 로직을 담는 것은 가능하다는 점도 DTO와 차이가 있다.
References
'CS > Spring' 카테고리의 다른 글
[Spring] DI의 세 가지 방법(필드 주입, 생성자 주입, setter 주입) (0) | 2023.04.21 |
---|---|
[Spring] 스프링에서 빈 객체를 등록하는 방법(@Bean, @Component) (0) | 2023.04.14 |
[Spring] 비즈니스 로직이란? (0) | 2023.04.08 |
[Spring] Controller, Service, Repository (0) | 2023.04.08 |
[Spring] DI와 IOC에 대해서 (0) | 2023.04.05 |