처음 개발을 접했을 때 나는 단기간에 가시적으로 결과물이 나왔어야 했기 때문에
"일단 구현해보자." 라는 생각으로 열심히 구글링의 파도에 빠져서 복붙하기 바빴다.
과거의 나 (어쩌면 지금도 ㅎ)
그러다보면 여러 기술 블로그에서 DTO, VO 등의 단어를 클래스명에 삽입을 하게 되는 경우를 종종 볼 수 있다.
그때는 구현하기 바빴으니 복붙하기 바빴지만
개발자들이 명칭을 붙이고 통용되어 사용하는 이유가 있을 것이라고 생각이 들어
노션에 공부하며 정리해뒀던 것들을 슬그머니 꺼내본다.
Plain Old CLR (Common Language Runtime) Objects - from MS
Plain Old Java Objects - from 마틴 파울러
라고 불리는 이것은 명칭이 조금 다르지만 Plain에 초점을 맞추면 된다.
번역 그대로 순수한 객체로, 프레임워크에 종속적이지 않은 객체를 의미한다.
국내에 흔히 사용하는 Spring 프레임워크는 POJO 프로그래밍을 지향하고 있는데 규칙은 다음과 같다.
예를 들면, 비즈니스 로직을 처리하는 과정에서 request, session 등을 사용하는 것은 POJO를 위반했다고 볼 수 있다.
순수한 자바 객체를 의미한다.
Data Tranfer Object
말 그대로 데이터를 전송하는 객체다.
계층 간 데이터 교환을 위해 사용되는 객체로 흔히 View 계층과 Controller 계층에서 사용되는 객체이다.
데이터를 운반하는 것이 주 목적이기 때문에 비즈니스 로직을 포함하지 않으며 getter, setter 메소드만을 가진다.
심플하니까 설명은 패스.
Value object
값을 표현하는 객체.
어떤 블로그 보니까 VO와 Entity를 혼동하셨던건지 VO가 Entity인 것처럼 기술을 하셨던데 엄연히 다르다.
기본키로 식별 값을 가지며 도메인 객체를 정의하는 Entity와 다르게
도메인에서 한 개 또는 그 이상의 속성들을 묶어 특정 값을 나타내는 객체를 의미한다.
VO가 Entity와 구분되는 조건은 다음과 같다.
별도로 VO 생성하지 않고 원시 타입(private)만으로 프로그래밍을 할 수 있지만,
VO 생성하게 되면 도메인을 설계할 때 Entity가 지나치게 거대해지는 것을 막을 수 있고, 객체의 제약사항을 분리하여 보다 더 객체지향적으로 코드를 작성할 수 있다.
값이 미리 정해져있는 경우에는 미리 인스턴스를 생성한 후 캐싱하여 성능을 높이는 것도 고려할 수 있다.
비즈니스 로직을 포함할 수 있고 getter 메소드를 가질 수 있다.
데이터베이스와 실제로 매핑되는 객체이다.
이를 기준으로 테이블이 생성되고 스키마가 변경되기 때문에 이를 DTO처럼 전달 객체로 사용해서는 안된다. (기능은 작동하겠지만 그런 리스크를 굳이...?)
위에 언급한 것처럼 기본키로 식별 값을 가지며 비즈니스 로직을 포함할 수 있다. 상황에 따라 getter, setter 메소드를 포함할 수 있다.
POJO | DTO | VO | Entity | |
---|---|---|---|---|
비즈니스 로직을 가지는가 | yes/no | no | yes | yes |
내부 상태를 변경할 수 있는가 (가변 객체인가) | yes | yes | no | yes |
식별할 수 있는가 | yes/no | no | no | yes |
끝!
공감하며 읽었습니다. 좋은 글 감사드립니다.