프로젝트 구현에 앞서 DTO 와 Entity 변환에 대해 명확한 이해가 필요했습니다. 이제는 익숙해지기 위해 무작정 코드를 작성하는 게 아닌 왜 그런 코드를 작성했는지에 대한 심도 깊은 이해가 필요하다고 판단했습니다.
DTO <-> Entity 변환에 앞서 이 행위를 왜 ? 하는 지에 대해 튜터님께서 설명해주셨습니다.
우선, Entity , DTO 를 떠나서
Layer 아키텍처가 왜 구분되어 있는지에 대한 이해가 필요합니다.
: 이는 계층 별로 역할을 분리하기 위함입니다.
controller의 역할 : 요청 받은 후 처리된 응답을 돌려주는 역할
service 역할 : 풀어내야 하는 문제애 대해 집중하자!
repository 역할 : DB에 집중하자 !
(즉, 장비를 관리하는 저수준의 레이어)
# 검색 키워드 추천 :
- 저수준 고수준 레이어 ,
- 기능과 책임 분리 (객체지향에서 가장 중요한 개념)
또 이런식으로 계층이 구분되어 있는 구조에 대해 설명을 해보겠습니다.
바로 JVM 입니다.
JAVA -> JVM 바이트코드 -> JVM -> 기계어 -> 컴퓨터
개발자는 JAVA 에 대해서만 알면 JVM 이하 작업
(JVM 내부 동작이나 JVM에서 컴퓨터로 어떻게 데이터가 흐르는지 등)은 신경 쓰지 않아도 됩니다.
그 이유는 계층을 분리하여 역할과 책임을 분리하였기 때문입니다.
개발자는 JAVA 만 다루면 됩니다.
즉, 각 레이어는 본인 레이어가 가진 역할에 대해서만 알아야 합니다.
고수준의 레이어는 하위(저수준)의 레이어를 알 수 잇으나
반대로 하위 레이어는 고수준 레이어를 알면 안됩니다.
# 검색 키워드 추천 :
- DIP
- 의존성 방향
- 의존성 역전
이제 다시 DTO 와 Entity로 돌아오겠습니다.
레이어 분리로 인해 다른 레이어 간의 데이터 전송을 위해 사용되는 객체가 필요합니다.
이게 DTO 의 "역할" 입니다.
Entity는 주로 데이터베이스와 직접적인 상호작용을 담당하는 객체입니다.
DB와 통신할 때 사용되는 객체, 그것이 Entity의 "역할" 입니다.
레이어 관점에서 DTO는 Entity보다 고수준이라고 할 수 있습니다
그러므로
DTO는 Entity를 알아도 되지만
Entity는 DTO를 알면 안됩니다.
+ 참고로 "안다"라는 표현은 코드에서 객체 간의 의존성 또는 참조 관계를 의미
# 검색 키워드 추천 :
- 클래스 연관 관계 의존관계
만약 Entity가 DTO를 알게 되면 (= ex Entity에서 DTO를 반환하는 메서드를 정의할 경우)
DIP 를 위반하는 행위가 됩니다.
우선 Entity <-> DTO 간 변환에 라이브러리를 이용하는 케이스를 생각해보겠습니다.
라이브러리(ex ModelMapper 라이브러리나 MapStruct)를 이용할 경우 다음과 같은 장단점이 있습니다.
- 여러 방법들 중 제일 코드 작성하기 쉽다
- 하지만 유연성이 떨어진다.
- DTO 와 엔티티가 일치성이 높으면 써도 됨
- 과제나 이런것에선 쓰겠지만, 실무에서 쓰진 않음
DTO <-> Entity 변환 하는 과정에 대해 DTO -> Entity / Entity -> DTO 로 구분하여 생각해보겠습니다.
DTO -> Entity로 변환하는 경우
1. DTO에서 Entity 만들기 - DTO 내부에 변환 메서드 생성
- 내부에 변환 메서드를 만들고, 객체는 보통 빌더 패턴으로 생성
예시 )
- 코드 출처 : chat gpt
@Getter
public class UserDTO {
private String username;
private String email;
private int age;
// toEntity 메서드
public UserEntity toEntity() {
return UserEntity.builder()
.username(this.username)
.email(this.email)
.age(this.age)
.build();
}
}
# 검색 키워드 :
- 빌더 패턴
- 이펙티브 자바 아이템 1 , 아이템 2
2. Mapper 클래스로 빼기
- 만약, 가독성이 너무 떨어지면 Mapper 클래스로 빼도 좋다.
Entity -> DTO로 변환하는 경우
※ 우선 유의할 점은 Entity는 내부에 DTO 변환하는 메서드가 존재하면 안된다.
1. Mapper 클래스를 만들어서 Entity -> DTO 만들기 (2가지 방법 존재)
- Service 클래스 내부에 Mapping 을 위한 private Mapper 클래스 만들기
- Service 와 동일한 패키지에 Mapper 클래스 파일 만들기
2. Service 클래스 내부적으로 private 변환 메서드 만들기
예시 )
- 코드 출처 : chat gpt
public class UserService {
// Public method that uses the private convertToDto method
public UserDTO getUserDto(UserEntity userEntity) {
return convertToDto(userEntity);
}
// Private method that converts UserEntity to UserDTO
private UserDTO convertToDto(UserEntity userEntity) {
return new UserDTO(
userEntity.getId(),
userEntity.getName(),
userEntity.getEmail()
);
}
}
회고
단순히 변환 방법을 공부하는 것에 그치지 않고, 근본적인 의문을 고민할 수 있어 정말 유익했습니다. 설계에 대해 항상 의문을 품고, 객체 지향적으로 응집도를 높이고 결합도를 낮추는 방법을 고민하는 자세가 필요하다고 느꼈습니다.
'스파르타 > TIL' 카테고리의 다른 글
2024.08.29 | EntityGraph 또는 Fetch Join (0) | 2024.08.29 |
---|---|
2024.08.28 | casecade = CascadeType.REMOVE vs orphanRemoval = true (0) | 2024.08.28 |
2024.08.26 | API 설계서 작성 가이드 (0) | 2024.08.27 |
2024.08.23 | API 명세서 작성 시 소프트 딜리트에 대한 HTTP 메서드 선택 기준 (0) | 2024.08.23 |
2024.08.12 | 도커 vs 가상머신 (0) | 2024.08.12 |