DAO, DTO, VO
MVC 패턴
Controller 의 역할
- 중간에서 Model 과 View 의 연결 담당
- 비즈니스 처리 로직 (Model) 과 UI 영역 (View) 은 서로 존재 인지를 못한다.
- View 로부터 들어온 사용자 요청을 해석하여 Model 을 업데이트
- Model 로부터 데이터를 받아 View 로 전달하는 작업 수행
- Model 과 View 사이의 의존성을 낮추고 독립적 개발을 가능하게 한다.
Controller 의 DTO 사용
- Controller 는 View 와 Model 의 데이터를 주고 받을 때 DTO 사용
- 도메인 객체를 직접 View 에 전달할 때 문제점
- 민감한 도메인 비즈니스 기능이 노출될 수 있다.
- Model 과 View 사이에 의존성이 생길 수가 있다.
비즈니스 노출 예시
Member.java
public class Member {
public Long id;
public String name;
public String email;
public String password;
}
MemberController.java
@GetMapping
public Member show(@PathVariable long id) {
Member member = memberService.findById(id);
return member;
}
- Controller 가 응답으로 도메인 Model 인 Member 를 넘겨줄시 문제점
- 도메인 Model 의 모든 속성이 외부에 노출
- UI 화면마다 사용하는 Model 의 정보는 상이하지만 Model 객체는 UI 에서 사용하지 않을 불필요한 데이터까지 보유
- 비즈니스 로직 등 Member 의 민감한 정보가 외부에 노출되는 보안 문제와도 직결
- UI 계층에서 Model 의 메서드를 호출하거나 상태를 변경시킬 위험이 존재
- Model 과 View 가 강하게 결합되어 View 의 요구사항 변화가 Model에 영향을 끼치기 쉽다.
- User Entity 의 속성이 변경되면 View 가 전달 받을 JSON 및 프론트엔드 JS 코드에서도 변경을 유발
DTO 사용 예시
MemberDto.java
public class MemberDto {
public final long id;
public final String name;
public final String email;
public static MemberDto from(Member member) {
return new MemberDto(member.getId(), member.getName(),member.getEamil());
}
}
MemberController.java
@GetMapping
public ResponseEntity<MemberDto> show(@PathVariable long id) {
Member member = memberService.findById(id);
return ResponseEntity.ok().body(MemberDto.from(member));
}
- DTO 를 사용해서 문제 해결
- 도메인 Model 을 캡슐화하고 UI 화면에 사용하는 데이터만 선택적으로 보낸다.
- UI 화면마다 DTO 구현
- DTO의 계층간 전달자 역할
- 클라이언트 요청에 포함된 데이터를 담아 서버에 전달
- 서버 측의 응답 데이터를 담아 클라이언트에 전달
Layered Architecture
https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/
- 유사한 관심사들을 레이어로 나눠서 추상화하여 수직적으로 배열하는 아키텍처
- 하나의 레이어는 자신에게 주어진 고유한 역할 수행
- 인접한 다른 레이어와 상호작용
- 재사용성과 유지보수에 유리
- 특정 레이어 수정 및 개선시 시스템 전체를 수정하지 않아도 된다.
DTO Data Transfer Object
- dto package
- 계층 간 (Controller, View, Business Layer) 데이터 교환을 하기 위해 사용하는 객체 (Java Beans)
- 로직을 가지지 않는 순수한 데이터 객체 (getter & setter)
- DTO 가 DB 데이터를 임의로 조작할 필요가 없기 때문에 Setter 불필요 → 생성자에서 값을 할당한다.
DAO Data Access Object
- repository package
- 데이터베이스의 데이터에 접근하기 위한 객체
- 데이터베이스에 접근하기 위한 로직과 비즈니스 로직을 분리하기 위해 사용
- CRUD
VO Value Object
- 값 오브젝트로써 값을 위해 쓰인다.
- read-Only 특징
- DTO와 동일시 하는 경우가 많다.
Entity Class
- domain package
- 실제 DB 의 테이블과 매칭될 클래스
- 가장 Core 한 클래스
Entity 클래스 생성시 주의사항
무분별한 setter 메서드 생성
- 보통 자바빈 규약을 생각하며 getter/setter 를 무작정 생성
- → 해당 클래스의 인스턴스 값들이 언제 어디서 변해야하는지 코드상 명확히 구분 불가
- → 차후 기능 변경시 복잡해진다.
- 해당 필드의 값 변경이 필요하면 명확히 그 목적과 의도를 나타낼 수 있는 메서드 추가
Entity 와 DTO 간 분리 이유
- Entity 는 값이 변경되면 다른 로직에도 영향을 미친다.
- DTO 클래스는 View Layer 와 데이터 교환이 빈번하기 때문에 DTO 와 Entity 를 분리함으로써 View Layer 와 DB Layer 분리 가능
- View 에서 요청하는 정보와 DB Table 에 Mapping 되는 정보가 다를 경우, 필요한 정보에 맞게 로직이 추가로 필요하게 되어 번거롭다.
- DB 로부터 조회한 Entity 를 View 로 전달할 경우 불필요하거나 기밀 정보까지 노출될 수 있기 때문에 따로 구현하는 것이 좋다.
package 기준 구조
https://gmlwjd9405.github.io/2018/12/25/difference-dao-dto-entity.html