값을 담는 객체를 의미합니다.
예전에 DB에서 데이터를 가져올 때, Collection Framework
를 사용하여 데이터를 담았습니다.
- List<String>
과 같이 리스트의 인덱스가 의미하는 컬럼이 있고, 이에 해당하는 값을 String
으로 담는 방식, 이것이 하나의 튜플이고, 여러 개의 튜플을 담기 위해 List<List<String>>
을 사용하였습니다.
List<Map<String,String>>
을 도입하여, DB 튜플 하나를 Map<String,String>
으로 보고, 이 값들의 집합을 List
에 담는 방식으로 DB의 데이터를 어플리케이션의 객체로 매핑할 수 있었습니다.객체
에 담아보자는 아이디어가 나왔고, 이것이 VO
가 되었습니다.VO
는 추후 JPA
의 Entity
와 비슷한 역할을 하나, VO
는 불변으로 객체의 값을 담기 위해서만 사용되기에, 자기 자신의 상태를 변화시키는 비즈니스 로직을 내포할 수 없지만 Entity는 비즈니스 로직을 가질 수 있다는 점에서 차이가 있습니다.Entity
는 JPA Persistence Context
에 의해 관리되고, 엔티티의 수정사항을 반영할 때 Setter
보다는 Entity 중심의 도메인 로직으로 캡슐화하는 것이 좋습니다.계층과 계층 혹은 시스템과 시스템 사이에 데이터를 운반하는데에 쓰이는 객체입니다.
1) Spring MVC Framework는
소켓을 통해 들어온 HTTP 요청 Stream을 파싱하고, HTTP Header와 Body를 분석한 뒤
개발자가 직접 구현한 Controller
로 개발자가 정의해놓은 형식에 맞춰 데이터를 변환하여 전달해줍니다.
이 때, @RequestParam
, @PathVariable
, @ModelAttribute
, @RequestBody
등의 어노테이션을 통해 Spring MVC Framework에 해당 컨트롤러에서 바인딩 받고 싶은 포맷을 정의할 수 있는데, 이 중 @ModelAttribute
와 @RequestBody
를 통해 객체의 형식으로 Input Data를 받을 수 있습니다.
- @ModelAttribute
는 Query String
에 있는 데이터의 조합을 묶어서 미리 정의해놓을 수 있고, 해당 객체는 DTO
의 일종이라 할 수 있습니다.
@RequestBody
는 HTTP Request Body
의 데이터를 객체로 받아서 Controller
에 받을 수 있습니다. 이 때의 객체 또한 DTO
의 일종이라 할 수 있습니다.2) Controller는 비즈니스 로직을 효율적으로 처리하기 위해 Service 계층을 두어 내부에 참조할 수 있습니다. ( = Spring Framework의 IoC Container를 통해 DI 받을 수 있습니다. )
또한, Service 계층은 DB에 Access하기 위한 계층인 DAO 혹은 Repository 계층을 내부에 참조할 수 있습니다.
이 때, Controller
에서 Service
로 데이터를 넘길 때의 스펙을 하나의 객체로 캡슐화한다면, 추후 넘어갈 데이터의 종류/타입이 바뀔 때 해당 객체 부분만 수정할 수 있어, 수정 범위가 줄어드는 이점이 있습니다. ( 유지보수성 )
이와 마찬가지로, Service
에서 Controller
로 데이터를 넘길 때, DB에서 조건에 맞게 조회한 Entity 자체를 넘기기 보다 Entity 내용 중 보여줄 부분을 캡슐화하여 넘겨준다면, 유지보수성은 물론이고 보안을 지킴은 물론 및 컨트롤러의 복잡도 또한 낮출 수 있을 것입니다.
위의 Controller
<-> Service
사이의 데이터 교환을 위한 객체를 캡슐화할 수 있으며, 이 객체는 DTO
의 일종입니다.
- 하지만, `Controller` 에서 `Service`로 `DTO`를 만들어서 보내는 경우는 드문 것 같습니다. 왜냐하면 `Spring MVC Framework`가 바인딩 해준 `DTO` 자체가 비즈니스 로직에 필요한 아규먼트 값들을 가지고 있을 확률이 매우 높기 때문입니다.