티스토리 뷰
백엔드 공부를 하다 보면, 데이터를 다루는 객체의 이름에 ~~Dto, ~~VO, ~Entity 같은 것들이 붙어 있는 것을 자주 볼 수 있다. 처음에는 정의도 모르고 어떤 경우에 어떤 종류를 사용하는 지 잘 모르고 남용했다. 그러나 정의와 역할, 용도 등은 알아둬야 적절한 객체를 사용할 수 있고, 또 각각에 존재하는 제약조건 등을 지켜야 일관성 있는 패턴으로 개발을 할 수 있을것 같아 이번 기회에 알아보려고 한다.
1. DTO (Data Transfer Object)
DTO는 계층간 데이터 교환을 위한 객체이다. DB의 데이터를 Service나 Controller 등 다른 계층으로 보낼 때 DTO로 변환하여 보내고 받게 된다.
DTO는 로직을 갖지 않고, 오로지 필드만 가지는 순수한 데이터 객체이다.
개발자의 성향에 따라 setter로 필드를 초기화하거나, 생성자로 필드를 초기화하는 법 등 주로 두 가지 방법을 쓰는 것 같다. 보편적으로 두 경우 모두 getter는 열어둬 값을 get할 수 있게 한다.
- setter를 이용하는 경우
setter를 열어두는 경우, 객체 생성 후에도 언제든 객체의 상태가 변할 수 있으므로 가변 객체이다.
@Getter
@Setter
public class StudentDto {
private Integer id;
private String name;
private String department;
}
- 생성자를 이용하는 경우
생성자로 초기화하는 경우, 객체 생성 시점 이외에는 객체의 상태가 변하지 않으므로 불변 객체이다,
@Getter
public class StudentDto {
private Integer id;
private String name;
private String department;
public StudentDto(Integer id, String name, String department) {
this.id = id;
this.name = name;
this.department = department;
}
}
2. VO (Value Object)
VO는 값 객체, 즉 값 자체를 표현하는 객체이다. VO는 참조하는 객체가 달라도, 객체의 상태, 즉 값들이 같다면 동일한 객체라고 간주한다. 따라서 equals()와 hashCode() 메소드를 오버라이드해야 한다.
DTO와 마찬가지로, setter에 대해서는 개발자의 성향마다 활용 방법이 다양한 것 같다.
그러나 VO는 getter와 함께 추가적인 비즈니스 로직도 포함할 수 있다.
@Getter
public class StudentVO {
private Integer id;
private String name;
private String department;
public StudentVO(Integer id, String name, String department) {
this.id = id;
this.name = name;
this.department = department;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
StudentVO vo = (StudentVO) o;
return Objects.equals(id, vo.id) && Objects.equals(name, vo.name) && Objects.equals(department, vo.department);
}
@Override
public int hashCode() {
return Objects.hash(id, name, department);
}
}
3. Entity
Entity는 실제 데이터베이스의 테이블과 1:1로 매핑되는 클래스이다. 따라서 테이블에 존재하는 Column만을 필드로 가져야 한다. Entity 객체는 Persistence와 관련된 객체이므로 계층 간 데이터를 전달하는 용도로 사용해서는 안 된다.
로직을 구현할 수 있으나, 도메인 관련 로직만 가지는 것이 좋으며, 비즈니스 관련 로직은 엔티티의 값을 DTO를 통해 Service 레이어로 전달하여 구현하는 것이 좋다.
- 도메인 모델 패턴 : 엔티티가 비즈니스 로직을 가지고 객체지향의 특성을 적극 활용하는 것
- 트랜잭션 스크립트 패턴 : 엔티티에는 비즈니스 로직이 거의 없고 서비스 계층에서 대부분의 비즈니스 로직을 처리하는 것
Entity 클래스는 객체의 무분별한 상태 변화 방지 및 유지 보수의 용이를 위해 정말 필요한 경우가 아니라면, setter는 닫아 두고 필요한 경우에만 열어 한정적으로 사용하는 것이 좋다고 한다.
(JPA를 슬슬 공부 중인데, JPA를 더 알아본 뒤 자세히 작성하도록 하겠다.)
Reference
'개발 > 스프링 일기' 카테고리의 다른 글
[03] Oracle DB 실행계획, 인덱스, ROWNUM, Pagination (1) | 2022.01.16 |
---|---|
[03] 스프링 MVC의 구성 (2) | 2021.11.30 |
[02] Spring + IntelliJ + 오라클 클라우드 데이터베이스 (with JDBC) (3) | 2021.11.23 |
[01] IntelliJ에서 Spring 프로젝트 생성하기 (MacOS) (4) | 2021.11.23 |
[00] Spring Framework 시작 (1) | 2021.11.23 |
- Total
- Today
- Yesterday
- Canny Edge Detector
- 오라클 클라우드
- pagination
- 코드로 배우는 스프링 웹 프로젝트
- JVM 메모리 구조
- 경기지역화폐
- DTO
- 오라클 데이터베이스
- 싱글톤
- 객체지향
- 인텔리제이
- 경기도 청소년 교통비 지원
- 실행 계획
- M1 맥
- IntelliJ
- hint
- Java
- Non Max Suppression
- Thresholding
- runtime data area
- m1 mac
- 강남면허시험장
- spring
- 경기버스
- 1종대형
- 경기교통비지원
- jvm
- Edge Detector
- 오라클 JDBC
- 컴퓨터비젼
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |