DAO와 Repository / dto와 VO에 대한 생각
blog.naver.com
필자의 블로그 [커리어리 글을 작성하는 것이 다소 익숙하지 않기에, 아래 블로그로 가면 가독성이 더욱 좋을 것 입니다.]
https://blog.naver.com/PostView.naver?blogId=gomets_journey&logNo=223220338105&parentCategoryNo=&categoryNo=26&viewDate=&isShowPopularPosts=false&from=postList
우선 각 용어와 패턴에 대해 이야기 해보려한다.
DAO (Data Access Object)
DAO는 데이터 액세스 작업을 추상화하고 데이베이스와의 상호 작용을 관리하는 객체로써 주요 역할은 다음과 같다.
데이터 액세스 추상화 : DAO는 데이터베이스 연결, 쿼리 실행, 결과 처리 및 트랜잭션 관리와 같은 데이터 액세스 관련 작업을 캡슐화한다.
데이터베이스 종속성 감소 : DAO는 도메인 로직이 데이터베이스와 직접 상호 작용하는 것을 방지하고, 도메인 로직을 데이터베이스 종속성으로부터 격리시킨다.
코드 재사용 및 중복 제거 : DAO를 사용하면 데이터 액세스 코드를 여러 곳에서 재사용할 수 있으며, 중복 코드르 방지하여 유지 보수성을 향상시킨다.
Repository
Repository 패턴은 데이터 저장, 검색 및 관리를 추상화하고 도메인 레이어와 데이터 액세스 레이어 간의 중재자 역할을 수행하는 패턴이다. 주요 특징은 다음과 같다.
도메인 로직과 분리 : Repository는 도메인 로직에서 데이터 액세스에 대한 직접적인 의존성을 줄인다. 도메인 객체는 Repository를 통해 데이터를 가져오거나 저장한다.
CRUD 작업 제공 : Repository는 주로 CRUD(Create, Read, Update, Delete) 작업을 제공한다. 도메인 객체의 생명주기를 관리하고 데이터 액세스를 추상화한다.
다양한 데이터 소스 지원 : Repository는 데이터베이스 외에도 파일, 웹 서비스, 메모리 등 다양한 데이터 소스를 지원할 수 있다.
DTO (Data Transfer Object)
DTO는 데이터를 전달하거나 전송하기 위한 객체로, 주로 데이터를 간결하게 표현하고 전송 효율을 높이는 데 사용된다. 주요 특징은 다음과 같다.
데이터 전송용 : DTO는 주로 데이터를 전송하기 위해 사용된다. 데이터베이스나 외부 시스템과의 데이터 교환을 용이하게 한다.
데이터 가공 및 필터링 : DTO는 필요한 데이터만을 포함하고 불필요한 정보를 필터링하여 전송 효율을 높이는 역할을 한다.
가볍고 변경 가능 : DTO는 보통 불변 객체보다 가볍고 변경 가능한 객체로 사용된다. 데이터 전송 목적이므로 객체 상태 변경이 더 자유롭게 허용된다.
VO (Value Object)
VO는 불변하며 값을 나타내는 객체이다. 주로 도메인 모델에서 사용되며, 다음과 같은 특징이 있다.
불변성 : VO는 불변한 속성을 가지며, 생성 후에는 변경할 수 없다. 이로써 예측 가능하고 안정적인 동작을 보장한다.
동등성(Equivalence) 기반 비교 : VO는 동등성을 기반으로 두 객체가 동일한 값을 가지는지 판단한다. 이러한 비교는 값 자체에 중점을 둔다.
값의 개념을 표현 : VO는 주로 개념적으로 하나의 값을 나타내는 데 사용된다. 금액, 날짜 범위, 주소 등이 VO의 예이다.
이제 DAO와 Repository의 차이점에 대해서 이야기해보고자 한다.
목적 및 역할
DAO (Data Access Object) : DAO는 주로 데이터베이스와 직접 상호 작용하는 데 중점을 둔다. 데이터베이스 테이블에 대한 CRUD(Create, Read, Update, Delete) 작업을 수행하는 메서드를 제공하고 데이터베이스 연결, 쿼리 실행 및 결과 처리와 같은 데이터 액세스 작업을 추상화한다.
Repository : Repository는 비즈니스 로직과 데이터 액세스 레이어 사이의 중개자 역할을 한다. 도메인 객체를 데이터베이스나 다른 데이터 소스로부터 가져오거나 저장하는 작업을 수행하며, CRUD 작업을 추상화하고 도메인 레이어에서 데이터 액세스에 대한 직접적인 의존성을 줄인다.
2. 도메인 관점
DAO (Data Access Object) : DAO는 주로 데이터베이스의 테이블과 관련된 엔티티와 연관된 작업을 처리한다. 각 DAO 클래스는 특정 엔티티와 관련된 데이터 액세스 로직을 포함한다.
Repository : Repository는 도메인 객체와 관련된 작업을 처리한다. 도메인 객체가 특정 엔티티를 나타내는 경우, Repository는 이러한 도메인 객체와 관련된 데이터 액세스를 추상화하고 관리한다. 즉, 도메인 객체 중심의 접근 방식을 채택한다.
3. 데이터 소스 관리
DAO (Data Access Object) : DAO는 주로 특정 데이터베이스와 연관되며 해당 데이터베이스와 직접 상호 작용한다. 따라서 각 DAO 클래스는 특정 데이터베이스 테이블 또는 데이터 소스에 대한 로직을 가진다.
Repository : Repository는 여러 데이터 소스를 지원하고 데이터베이스 외의 다른 데이터 소스와도 상호 작용할 수 있다. Repository는 데이터 소스에 대한 접근을 추상화하므로 동일한 인터페이스를 사용하여 다양한 데이터 소스를 지원할 수 있다.
4. 추상화 수준
DAO (Data Access Object) : DAO는 주로 데이터베이스와의 특정 테이블 수준의 상호 작용을 추상화한다. 이는 데이터베이스 스키마와 밀접하게 연관된다.
Repository : Repository는 데이터베이스나 다른 데이터 소스와의 상호 작용을 더 높은 수준으로 추상화한다. 도메인 객체 레벨에서 데이터를 관리하며, 도메인 논리에 더 가깝게 다가간다.
요약하자면, DAO는 주로 데이터베이스와의 저수준 상호 작용을 추상화하고 데이터베이스 테이블과 밀접한 관련이 있으며, Repository는 도메인 객체 중심의 데이터 액세스를 추상화하고 다양한 데이터 소스를 지원하는데 더 중점을 둔다. Repository 패턴은 도메인 레이어와 데이터 액세스 레이어 간의 느슨한 결합을 촉진하여 유지 보수성과 테스트 용이성을 향상시킨다.
이제 내 개인적인 생각에 대해서 좀 더 이야기 해보려한다.
dto는 데이터를 옮겨줄 수 있는 객체를 의미하는데 dto가 왜 필요하냐는 것 부터 생각을 해보아야 한다.
우선 엔티티는 JPA에 의해 DB 테이블에서 직접적으로 관리를 하게 된다. 그리고 영속성 컨텍스트에서도 관리가 되어진다. 이것을 어떻게 식별할 수 있는지는 PK로 인해 가능하다. 하지만 dto는 그렇지 않다. 그렇다면 dto는 어떻게 관리가 되어지는 것일까를 생각해보아야한다. 그것은 Builder 패턴을 이용하여 그것을 엔티티로 다시 매핑을 하는 구조로 이용하게된다. 엔티티에 getter, setter를 사용해도 상관이 없긴하지만, DB에 직접 접근가능한 객체에 setter를 즉 자바 프로퍼티 방식을 적용한다면 변경상황에 대한 관리가 힘들어지게되고 추후 잦은 변경으로 인하여 자기가 예측하기 힘든 값들이 나올 수 있어 위험하다는 것이다. 이것을 방지하기 위해서 dto라는 개념이 나온 것이고 또한 그렇기 때문에 dto가 getter, setter가 가능하다고 생각한다. 근데 만약 어떤 객체는 readOnly만을 이용해야 할 경우에는 VO를 이용하는 것이 더 안정적일 수 있다. 실제로 transactional을 readOnly = true로 설정하면 읽는 작업만 수행하는 것에 대해서 성능이 향상되게 된다. 그리고 DAO를 설명하기 위해서는 Repository하고의 차이점을 알고 있어야 한다고 생각한다. 이 둘은 상당히 유사한 관계를 가지고 있어, 아직 그 둘을 분명히 분별하기에는 다소 부족하지만 DAO의 구성 패턴을 봐보면 DAO는 쉽게 비즈니스 로직과 DB접근 로직을 분리하자는 움직임이다. 이는 꼭 WAS와 Web Server와 비슷한 느낌을 받기도한다. 이는 단일 책임 원칙(SRP)을 지키기 위한 것이 아닌가 하고 생각을 해본다. 근데 DB접근 로직이라는 것은 결국 회사마다 조금씩 달라질 수 있기때문에 이를 방지하기 위해서 Adapter 패턴이 적용되게 된다. 그리고 어느 한 DB에 종속적이지 않도록 어느 한 밴더의 구현체를 그대로 이용하지않고 DAO란 객체로 한 번더 감싸서 개방-폐쇄 원칙(OCP), 의존관계 역전 원칙(DIP)을 방지하였다라고 생각한다. 결정적으로 DAO는 모든 데이터 이동을 dto로 받겠다는 것이 있지 않을까 생각한다. Request, Response까지 전부 엔티티를 클라이언트와 분리시키자는 것이다. 반대로 Repository는 DDD 패턴이 적용된 기술인다. Repository의 경우는 엔티티를 직접적으로 이용하여도 설계상 문제될 것은 없긴하다. 위험하지만...
정리하자면 DAO란 DB 테이블에 1대 1로 연관지어져서 이용하는 것이 보편적이다 그리고 이전에는 SQL Mapper을 사용하여 SQL을 매핑하여 접근하였기에 객체라는 인식이 강하게 되었지만 지금은 ORM이 나오게 사용되어지면서 객체 그 자체를 DB에 연관지어서 생각하게 되었다. 즉 엔티티를. 물론 그에따라 SpringDataJPA나 QueryDSL 등이 나오면서 코드상에서 SQL이 많이 사라지게 된 것도 한 몫을 하고있다고 생각한다. 근데 DAO는 위에서 엔티티와는 상반되는 개념이다보니 이러한 점에서 차이가 있게 된다.
나는 현재 이렇게 이해를 하고있다. 이것이 정확하지 않을 수 있고 추후에 생각이 달라질 수 있으나 지금의 나는 이렇게 생각하고 있었구나 라는 것에 의의를 두고 기록해보려한다. 이러한 생각이 성장을 위한 거름이 되었으면 좋겠다.
다음 내용이 궁금하다면?
이미 회원이신가요?
2024년 3월 13일 오후 4:24
올
... 더 보기필자는 SI 프로젝트를 수행하는 회사에서 30년 넘게 근무하고 있다. 그동안 프로젝트를 수행하는 기술과 도구는 비약적으로 발전했다. 가장 큰 발전은 의사소통 도구의 혁신이다. 휴대폰이 등장으로 전화 통화가 쉬워졌고, 이메일/메신저/화상회의 도구는 보편화되었다. 30년 전에는 휴대폰, 메일, 메신저가 없이 고객이나 프로젝트 팀원과 소통하려면 유선 전화기와 대면소통 외에는 방법이 없었다.
... 더 보기잘
... 더 보기리