[DDD] Whiteship’s DDD 아키텍처 수정


Repository 역할이 DAO로 단순 위임 밖에 없어서, Repository를 없애고 그 자리에 DAO를 뒀습니다. Entity에서 이 객체를 사용하여 필요한 작업들을 할 겁니다. 이전의 Facade 역시 이름을 Service로 바꾸고, Transaction을 책임지게 했습니다. 이 서비스는 별다른 역할 없이 Domain 객체나 Dao로 역할을 위임하는 Thin Service입니다.

구조는 기존의 계층형 구조(Controller -> Service -> Dao)와 거의 비슷해 보이지만, 일단 Entity에서 Dao를 들고 예전에 서비스 계층에서 처리했던 비즈니스 로직을 담당하게 되었다는 것, 그 결과 Service의 일은 도메인 객체로의 단순 위임으로 바뀌었다는 점이 주요 특징으로 볼 수 있겠습니다. 또한, 모든 domain 클래스에 대한 C, S, D를 만들던 것과 달리 Entry Point에 해당하는 Entity에 대해 C, S, D를 제공하는 구조입니다. 즉 그림에서 Address라는 Value 타입과 OrderLine이라는 레퍼런스 타입에 대한 C, S, D는 볼 수 없죠.

6 thoughts on “[DDD] Whiteship’s DDD 아키텍처 수정”

  1. Repository 를 DAO로 대체할수 있는건가요? (http://whiteship.me/1305 이글에서 토비님이 어떻게 설명하셨는지 궁금해요.) DDD에서 말하는 Service와 ROO에서 말하는 Facade(Middle-Tier)는 다른 것 같다는 생각도 듭니다.

    그런데 위에서 application tier가 꼭 필요하나요? Ben이 마지막에 DTO를 ROO에서 제거했다는데 왜 그랬을까요…

    1. DAO로 Repository를 대체한 거라기보단, Repository 역할을 하는 녀석 이름을 짧게 DAO라고 부르기로 했습니다. 하이버네이트를 쓸 경우 굳이 객체 컬렉션(Repository)을 별도로 다룰 필요도 없을 것 같고, 이름도 좀 짧으니까요.

      DDD의 Service를 두 종류로 나눠 볼 수 있겠는데요. 위에서 사용한 Service는 트랜잭션을 담당하는 퍼사드 역할을 합니다. 이 녀석이 둘 중 하나인 thin facade로 볼 수 있겠죠. 나머지 한 부류인 email, jms, jmx 같은 기반 시설들은 infra service로 보고, 별도의 패키징으로 구분하기로 했습니다. 이름은 둘 다 동일하게 Service라는 접미사를 쓰구요.

      application tier를 둔 이유는 트랜잭션 처리 때문입니다. ROO에 보면, Entity_~~.aj의 메서드에 @Transactional 애노테이션으로 트랜잭션 처리를 하고 있습니다. 즉, DAO 내기 Repository에서 트랜잭션을 담당한다는 건데.. 그럴 경우 여러 도메인에 걸치거나 여러 DAO를 걸쳐 어떤 로직을 처리한다고 할 때 트랜잭션 처리 위치가 애매해지고, 사방으로 퍼질 가능성이 있어 보여서 thin facade 격인 serivce를 두고, 단순 위임만 하도록 application tier를 두었습니다.

      Ben이 DTO를 제거한 이유는 잘 몰게네요. @_@

  2. 안녕하세요^^ 이제 갓 2년차가 된 스쿨쥐라고 합니다. 기선님의 글을 보고 많이 배우고 있는 초보 개발자 중 한명입니다. 항상 좋은 글을 남겨주세셔 감사합니다.

    다름이 아니라 저도 DDD와 엔터프라이즈 애플리케이션 아키텍처 패턴을 보면서 프로젝트 규모에 따른 저만의 아키텍처를 구성하던 중 기선님의 DDD 아키텍처(수정전 버전)과 거의 동일하게 나오더군요. 수정본을 보니 약간 의문점이 생겨서요.

    이유인즉, 도메인 모델에서 Repository의 역할을 과연 DAO가 대체할 수 있는가 하는 문제입니다. Repository가 AGGREGATE별로 하나씩 생성되는데 위의 예제에서 Address나 OrderLine에 대해서 DAO가 관여하게 된다면 이미 DAO 구현체에 비지니스 로직이 섞여들어가는 것이 아닌가 생각됩니다. 만약 OrderLine에 대해서 별도의 DAO를 생성한다면 이는 Ropository의 개념에서 벗어나는 것이구요.

    제가 생각하기에는 기존 Ropository를 유지한 채로 OrderRepository에는 OrderDAO와 OrderLineDAO가 존재해야하기 때문에 Repository를 대체하기에는 조금 무리가 있지 않나 생각됩니다. 이는 이터너티님께서 언급한 글 중에도 나와있구요.(http://aeternum.egloos.com/1160846 – “결과적으로 REPOSITORY에서 제공하는 하나의 오퍼레이션이 DAO의 여러 오퍼레이션에 매핑되는 것이 일반적이다. 따라서 하나의 REPOSITORY 내부에서 다수의 DAO를 호출하는 방식으로 REPOSITORY를 구현할 수 있다.” )

    프로젝트의 규모에 따라 차이가 있겠지만 Repository에서 전략이 동적으로 바뀌어야할 경우, 예를들어 도메인을 메모리에서 먼저 검색하고, 없으면 프록시에서 검색하고, 또 없으면 메인 DB에서 검색해야하는 경우와 같은 부분에서는 DAO가 하기 힘든 일이라고 생각됩니다.(엔터프라이즈 아키택처 패턴에서 저장소부분의 예제를 보고 떠오른 생각입니다.)

    단순 용어의 차이일수도 있으나 Repository의 개념으로 사용하면서 DAO로 표현한다면 오해의 여지가 있지 않을까 해서 댓글을 남깁니다.(이터너티님의 글의 마지막 부분은 저는 이렇게 이해를 했습니다.)

    혹여나 공격적인 글로 오해하셔서 기분상하지 않으셨으면 합니다. 항상 기선님 글에서 많은 도움을 받는 개발자 중 한명이니까요 ^^. 항상 좋은 글 감사합니다.

    1. 와우. 멋진 의견이십니다. 저도 우연히 오늘 다시 이터너티님의 DAO와 리파지토리에 대한 글을 다시 읽으면서 스쿨쥐님과 비슷한 생각을 했었습니다.

      시간이 되면 이 구조의 아키텍처를 다시 개선해서 DDD 구현에 도전해봐야겠습니다.

      ps: 위 아키텍처 적용은 실패했습니다. T.T

  3. 참, 규모가 작은 프로젝트라면 트랜잭션 스크립트 + 액티브레코드 + 서비스레이어(도메인 퍼사드 접근방법) 조합도 컴포넌트 분리의 측면에서 바라볼 때 괜찮다고 생각됩니다. ^^ 개발속도나 스터디 비용에 있어서는 굉장히 유용하다고 생각됩니다. (but 저는 이 조합을 선호하지는 않습니다. 다만 개발하다보면 개발자의 역량을 생각한 아키텍처도 중요하다고 생각되는군요.)

    1. 저는 ROR이나 Grails에 대한 경험이 없어서 잘 모르겠지만, 작은 프로젝트 부터 한 번 적용해봐야겠습니다. 조언 감사합니다. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *