티스토리 뷰

Spring

[Spring] Entity VS DTO VS VO

PeonyF 2023. 3. 7. 18:51
반응형

Entity:  DAO와 DB 테이블 매핑하는 객체

  • Entity 클래스는 실제 DataBase의 테이블과 1 : 1로 매핑되는 클래스
  • DB의 테이블내에 존재하는 컬럼만을 속성(필드)으로 가져야 한다.
  • 외부에서 getter 메소드를 이용하지 않도록 필요한 로직 구현
  • 객체의 불변성을 보장해야 하기에 setter 메서드를 지양하고 생성자(constructor) 또는 Builder을 사용
  • request, response 클래스로 사용 X

* request, response 클래스로 사용 X 이유

- SRP 원칙 위배

SRP(Single Responsibility Principle)은 클래스나 모듈은 하나의 책임만 가져야 한다는 원칙입니다. Request나 Response 클래스는 HTTP 요청이나 응답에 대한 정보를 담고 있으므로, Entity와 같은 데이터 모델링이 추가될 경우 SRP 원칙을 위반하게 됩니다.

 

- 확장성 문제

Request나 Response 클래스를 Entity 클래스로 사용하면, 추가적인 데이터 모델링이 필요한 경우 클래스를 확장하기 어려워집니다. 예를 들어, HTTP 요청에 대한 데이터 모델링 외에도 인증(authentication)이나 보안(security)에 대한 정보를 추가해야 할 경우, Request 클래스를 수정하는 것은 번거로울 뿐만 아니라 클래스 구조를 파괴할 수 있습니다.

따라서 Entity 클래스는 Request나 Response 클래스 안에 포함되는 형태로 사용하는 것이 좋습니다. 이를 통해 SRP 원칙을 지키며, 데이터 모델링에 대한 확장성도 보장할 수 있습니다.

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "email")
    private String email;

    // Getters and setters
}

 

*데이터 교환용으로 사용하면 안되는 이유?

Entity를 기준으로 테이블이 생성되고 스키마가 변경된다. 뷰가 변경될때마다 Entitu클래스가 변경되면 여러클래스에 영향을 준다. -> 요청이나 응답값을 전달하는 클래스로는 DTO를 사용

 

 

 

DTO (Data Transfer Object) : Layer 간 데이터 교환, 데이터 전달용

객체의 정보를 변경할 수 있기 때문에 데이터가 가변적

DTO는 계층(Layer) 간 데이터 교환이 이루어질 수 있도록 하는 객체

- JSON serialization과 같은 직렬화에도 사용되는 객체

- DTO는 getter, setter 메서드를 포함하며, 이 외의 비즈니스 로직은 포함하지 않는다.

- DTO는 주로 비동기 처리를 할 때 사용

 

public class UserDTO {
    private Long id;
    private String name;
    private String email;

    // Getters and setters
}

 

*Property(프로퍼티) 개념

 

사용이유

DTO는 위처럼 service와 controller 같은 계층간 데이터 교환을 위해 사용

한 화면에서 보여지는 데이터 값들을 객체화시키고 어떤 타입의 데이터를 받아올 것인지 정의하기 위해서도 사용

*sofeware layer란?

1.프레젠테이션계층 : 사용자 인테페이스를 다루는 계층

2.비즈니스계층 : 비즈니스 로직을 다루는 계층(사용자의 요구사항을 해결하기 위해 대이터를 처리하는 코드가 해당)

-> 데이터를 추출하고 조작합니다. 데이터베이스 액세스, 데이터 검증, 계산, 로깅 등의 작업을 수행

3.데이터 액세스 계층 : 데이터베이스나 파일 시스템 등에서 데이터를 읽고 쓰는 작업을 담당

 

*왜 계층을 나눌까?

  • 유지보수 : 각 계층의 책임이 명확해져서 코드 수정/유지보수시 다른계층에 영향을 주지 않음
  • 확장성 : 어플리케이션이 더 크고 복잡해질때 새로운 계층을 추가하면 됨

 

*왜 계층간 데이터 교환을 해야할까?

계층간 데이터 교환은 각 계층에서 사용하는 데이터 형식이 다를 경우 데이터 전달을 위해 필요한 과정

 

VO (Value Object) : 값을 갖는 순수한 도메인, 값 표현용

VO는 변경 불가능한(immutable) 객체

VO는 특정 비즈니스 값을 담는 객체

- 내용물이 값 자체를 의미하기 때문에 'read only'

- getter 메서드와 비즈니스 로직은 포함할 수 있음

 

 VO는 객체들의 주소 값이 달라도 데이터 값이 같으면 동일한 것으로 여긴다.

-> 값 비교를 위해 equals()와 hashCode() 메서드를 오버라이딩 해줘서 비교한다.

public class DateRangeVO {
    private final LocalDate startDate;
    private final LocalDate endDate;

    public DateRangeVO(LocalDate startDate, LocalDate endDate) {
        this.startDate = startDate;
        this.endDate = endDate;
    }

    // Getters
}

* VO는 그럼 어떤 경우에 사용해야 할까?

  • 데이터가 불변이어야 하고, 단순히 저장된 값을 불러와야 하는 경우
  • 데이터를 전달하거나 비교하는 데 사용
  • 값 자체가 중요한 경우 (ex. 금액, 주소, 전화번호 등 값 자체)
  • 불변성을 유지해야 하는 경우
  • 객체 간 비교가 필요한 경우(ex. 두 개의 금액을 비교하는 경우, 금액 객체는 VO로 구현)
  • 복합 객체의 일부로 사용될 경우(ex.날짜 범위를 나타내는 객체가 있을 때, 시작일과 종료일을 각각 VO로 구현)
  • 성능상 이점이 있는 경우

 ->  VO는 불변성을 유지하므로, 객체를 복사하는 것이 간단합니다. 이는 프로그램의 성능을 향상시킬 수 있습니다.

또한, VO는 스레드 안전성을 보장하기 때문에 멀티스레드 환경에서 사용하기에도 좋습니다.

  •  

 

 

Entity VS DTO

Entity는 데이터베이스에서 사용되는 객체로 비지니스 로직을 포함, DB와 1:1 맵핑됨 -> DB에 저장됨

DTO는 데이터 전송 객체로 비지니스 로직을 포함하고 있지 않고 단순히 데이터 전달하기 위한 용도로 사용됨 -> 네트워크 또는 서비 간의 데이터 전송 담당.

  Entiy DTO
용도 계층 간 데이터 전달을 위한 객체 데이터를 전송하기 위한 용도
담당 컨트롤러에서 비즈니스 로직으로 전달되는 데이터를 담당
(컨트롤러에서 생성되고, 비즈니스 로직에서 사용)
네트워크 또는 서비스 간의 데이터 전송
독립성 O
(데이터 전달을 위한 용도로 사용되는 것이므로, 도메인 모델과 같은 비즈니스 로직과는 별도로 관리되어야 하기 때문)

X
비즈니스로직 포함 여부 O X

 

 

 

DTO VS VO

DTO는 데이터 전송에만 사용되는 단순한 객체 -> DTO는 보통 데이터베이스나 외부 API와의 통신을 위해 사용

VO는 비즈니스 로직에서 사용되는 불변 객체  -> VO는 보통 도메인 모델에서 사용

 

*비지니스로직

실제 업무로직 : 해당 프로그램이 어떤 일을 수행하고 있는지를 나타내는 핵심적인 부분

ex. 은행 시스템에서의 비즈니스 로직입

  • 계좌 생성 : 고객이 은행에서 계좌를 만들 때, 고객 정보를 입력하고, 계좌 생성 요청을 받아 계좌를 생성하는 로직
  • 입금 : 고객이 계좌에 돈을 입금할 때, 입금 금액과 계좌 정보를 받아서, 계좌의 잔액을 업데이트하는 로직
  • 출금 : 고객이 계좌에서 돈을 출금할 때, 출금 금액과 계좌 정보를 받아서, 계좌의 잔액을 업데이트하는 로직
  • 이체 : 고객이 자신의 계좌에서 타인의 계좌로 돈을 이체할 때, 이체 금액과 계좌 정보를 받아서, 계좌의 잔액을 업데이트하는 로직

 

Spring의 MyBatis(Entity) vs JPA(VO)

MyBatis

  • sql 매퍼를 이용해서 sql쿼리와 DB 테이블을 직접 매핑하는 방식으로 동작 -> 개발자가 SQL쿼리를 직접 작성해야함
  • 개발자가 직접 작성한 SQL쿼리 결과 -> 객체로 변환 -> 이 객체를 Entity 클래스로 사용

JPA

  • 객체와 DB간의 매핑을 자동으로 처리하여 개발자가 직접 SQL쿼리를 작성할 필요가없음
  • JPA에서는 VO(Value Object)나 DTO(Data Transfer Object) 클래스를 사용하여 객체를 매핑

 

 

*참고

https://hendryluk.wordpress.com/2009/08/17/software-development-fundamentals-part-2-layered-architecture/

https://velog.io/@ygreenb/DTO-VO-Entity

 https://dev-coco.tistory.com/87

https://yeonyeon.tistory.com/163

https://wildeveloperetrain.tistory.com/101

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함