Spring - VO, DTO, Entity, DAO, Repository 개념과 계층구조

Y·2022년 8월 2일
0

Spring

목록 보기
1/3

스프링 공부를 했는데, VO, DTO, Entity, DAO, Repository 개념을 이해하고 정리해야할 필요가 있을 것 같다. 일단 내가 이해한 토대로 작성했기 때문에, 틀린 부분이 있을지도 모른다! (틀린 부분이 있으면 댓글로 알려주시면 감사하겠습니다.)

  • 일단 DB가 있다. DB에는 데이터가 담긴다. 그러면 그 데이터를 스프링 내에서 사용하기 위한 객체가 필요할 것이다. 여기에서 VO, DTO, Entity를 비교해볼 수 있다.

    • 순수하게 값 자체를 의미하는 것이 VO(Value Object)다. VO는 값을 저장하기만 하여, immutable하다. 객체들의 주소가 달라도 값이 같으면 동일하게 여긴다. setter 메소드는 가지지 않고, getter과 그 외 비즈니스 로직도 구현할 수 있다. equals, hashCode 메소드를 오버라이딩 해줘야된다.

    • 데이터를 계층들끼리 주고받아야 할 것이다. 그게 DTO(Data Transfer Object)다. getter/setter 메소드를 포함하고 그 외는 포함하지 않는다. 즉, 비즈니스 로직을 포함하지 않는다. setter을 사용하면 가변 메소드, setter 없이 생성자를 이용해 초기화하는 경우에는 불변 메소드로 사용할 수 있다. -> view와 DB 계층의 철저한 분리를 위해 DTO를 사용한다.

    • Entity의 경우에는 실제 DB 테이블과 매핑되는 핵심 클래스다. 테이블 내에 존재하는 컬럼만 속성으로 가져야 한다. 테이블 생성, 스키마 변경에 기준이 된다. id로 구분되고, 비즈니스 로직을 포함할 수 있다. controller의 request/response 클래스로 절대 사용해서는 안된다. (Domain으로 패키지를 생성하기도 하는듯) (참고. Entity의 경우 JPA의 Entity와 DDD의 Entity 개념이 혼용돼서 쓰이기도 하는 것 같은데 정확한 차이는 잘 모르겠다... 참조할만한 글)

  • VO, DTO, Entity 를 통해서 DB를 스프링에서 사용할 수 있게 됐다. 하지만 이걸로는 데이터를 사용할 수 있게 된 거고, 상위계층에서 뭘 하다보면 DB에 접근을 할 필요가 있을 것이다. 쿼리도 날리고 해야되지 않겠나. 음. 그런데 계층끼리 데이터를 주고받는 건 DTO가 하니까, 상위계층에서 DB에 접근하는 것도 DTO가 하는 일 아닌가? 얼핏 그렇게 생각할 수도 있겠지만. 아니다. DTO는 데이터 교환용 이다. getter/setter 메소드만 있다고 하지 않았나? 그러니까, 상위계층에서 DB에 CRUD 기능 구현하는 등등을 하려고 접근하기 위해서는 DB와 상위 계층 사이에, DB에 실제로 접근하고 결과를 상위 계층에 넘겨주는 뭔가 하나의 계층이 더 필요할 거다. (바로 접근하면 결합성이 너무 높아지고 레이어, 즉 웹 어플리케이션의 아키텍처가 깨지기 때문에 안된다.) 그 계층이 바로 DAO다. 오라클에 올라와있는 시퀀스 다이어그램인데, 이걸 보면 감이 잡힐지도 모르겠다. Transfer Object가 DTO다.

  • 어쨌든, 그러면 DAO가 뭔 일을 하는지는 어느정도 알겠다. 그런데 인터넷을 보다보면 Repository라는 개념이 보인다. DAO와 혼용되기도 한다. 이 둘의 차이는 뭘까? 일단 둘 다 하는 역할은 비슷해 보인다. DAL(Data Access Layer)의 구현이라고 한다. 사실 이 부분을 잘 모르겠어서 글을 많이 읽어봤는데, 아직도 정확하게는 이해를 못했다. 하지만 이해한 바로는 다음과 같다.

    • DAO는 실제 영구 저장소에 접근하는데, 이때 계층이 깨지지 않기 위해서 DTO를 사용한다. -> 영속성 객체로, infrastructure layer에 속한다.
    • Repository는 객체의 상태를 관리하는 저장소 이다. Entity(도메인 객체) 그 자체를 저장하고 불러온다. -> Domain layer에 속한다.

음. 뭔가 이상하다. DAO는 Infrastructure layer, Repository는 Domain layer라니? 하는 일은 다를 게 없어 보이는데. Repository는 일종의 컬렉션이다. -> Repository의 interface는 Domain layer에 있으나, 구현은 Infrastructure layer에 있다. 영구 저장소의 API를 이용하여 구현하는 것이다. 이렇게 되면서 domain, infrastructure의 의존성이 뒤집히게 되고(DIP) -> infrastructure에서 domain 레이어를 알아도 상관없으며, entity를 영속성 로직에 포함시킬 수 있는 것. 의존성이 역전되어있기 때문에 entity를 가져와서 영속성 로직을 수행할 수 있는 것이다. (그러면 DAO는 Entity를 바로 컨트롤하면 안 되나? 그렇다고 한다... DTO를 이용해야만 한다...)

포스팅1포스팅2, 포스팅3를 참조하였는데, 쭉 읽어보면 도움이 될 듯하다. (포스팅 4도 있는데, 이 글은 어려워서 아직 잘 이해하지 못했다.) DAO를 이용해 Repository를 구현할 수 있다고 하는데, 이 부분은 사실 잘 모르겠다. 아무튼 하는 역할은 비슷하지만 개념에 있어 차이가 있다(DAO는 데이터와 가깝고, Repository는 도메인 개체에 가깝다)고 생각하면 될 것 같다.

  • 그러면 이제 VO, DTO, Entity, DAO, Repository 개념들은 이해했다. 마지막으로 스프링 계층구조가 남았다. 스프링을 Web(Controller) - Service - Repository(DAO) 구조로 볼때, 다음과 같이 개념을 구분할 수 있다.

    • MVC 패턴에서 View에 속하는 부분은 frontend 파트일 것이다. C는 Controller, M은 Model이다.
    • Controller은 View와 Model(Service, DAO등이 Model에 속한다.)을 연결해준다. 프론트에서 API 요청을 보내면 그걸 매핑시켜주는 역할을 한다. 예를 들어 /users/login API 요청이 오면, 그와 매핑된 Controller은 적절한 Service를 호출시켜 주는 것이다. (이때 데이터를 주고받기 위해서는 DTO를 사용할텐데, 관련해서 참조할만한 글이 있다.)
    • 그러면 Service에서는 DAO를 호출하여 필요한 작업을 수행할 것이다.
  • 개념은 쉽다. 특히 MVC 패턴을 안다면 더 쉽게 이해할 것이다. 그런데 여기서 의문이 생길 수 있다. DAO를 통해 DB에 접근할 수 있는데, Controller에서 DAO에 바로 접근하면 안되나? Service가 굳이 필요한가?

    • 다시 한 번 DAO의 개념을 확인해보자. DAO는 DB에 접근한다. 이건 무슨뜻인가. 단일 데이터 접근/갱신이라는 뜻이다. 사용자가 보내는 요청이 단일한 데이터의 접근/갱신만으로 해결이 될까? 절대 아닐 거다. 그렇기 때문에 Service가 필요한 것이다. (단, Service와 DAO는 1:1 Mapping. 참조할만한 글1, 참조할만한 글2)
profile
개발자, 학생

0개의 댓글