본문 바로가기

🌱 우아한테크코스 6기

[코리스토텔레스] 패키지 구조: 계층형 구조 vs 도메인형 구조

https://github.com/woowacourse-6th-team99/2024-coristotle/discussions/3

패키지 구조: 계층형 구조 vs 도메인형 구조 · woowacourse-6th-team99 2024-coristotle · Discussion #3

패키지 구조를 계층형 구조로 생성하는 것이 좋을까, 도메인형 구조로 생성하는 것이 좋을까? 계층형 구조 예시 controller ⎿ ProductController ⎿ MemberController ⎿ ArticleController service ⎿ ProductService ⎿

github.com

 
코리스토텔레스는 본인의 설계에 철학을 갖기 위한 토론 스터디입니다. 해당 스터디에서 주장했던 입장을 정리한 글이므로, 저의 사견이 개입된 글임을 알립니다.


주제 선택 이유

총대마켓 팀 프로젝트 코드 컨벤션을 지정하는 과정에서 패키지 구조에 대해 논의한 적 있다. 그 당시 나는 도메인형 구조에 대해 무지한 상태였고, 당연히 나에게 익숙했던 계층형 구조로 코드를 작성하고 싶었다. 하지만 팀원들의 생각은 달랐다. 그들을 설득하고 싶었으나, 계층형 구조로만 코드를 작성해왔기에 도메인형 구조를 채택했을 때의 불편한 점을 알지 못했다. 계층형 구조를 채택했을 때의 장단점 또한 비교군이 없었기 때문에 체감하지 못했다. 결국은 직접 사용해보자는 마음으로 도메인형 구조를 받아들였다. 그 후 약 2주가 흐른 현재 시점에서 두 구조의 차이를 비교해보고 싶었다.

계층형 구조

controller
    - member
    - article
    - product

service
    - member
    - article
    - product

repository
    - member
    - article
    - product

domain
    - member
    - article
    - product

 
최상단 패키지를 controller, service, repository, domain과 같은 계층을 기준으로 분리한다.
 
내가 정의한 계층형 패키지 구조는 아래와 같다.
: 최상위 패키지는 계층형 구조로 정의하되, 하위 패키지는 도메인으로 분류하든 분류하지 않든 무관하다.

장점

도메인 설계에 영향을 받지 않는다.

  • 도메인을 어떻게 설계하였든 컨트롤러는 컨트롤러 클래스에, 서비스는 서비스 클래스에 위치시킨다.

도메인 지식이 부족한 경우에도 코드를 작성하기 어렵지 않다.

  • 패키지를 도메인으로 분리하지 않았다면, 도메인 지식과 코드 작성 난이도는 관련이 없을 것이다.

단점

하나의 기능을 구현하고 싶을 때 접근해야 하는 패키지 수가 많다.

  • 컨트롤러 → 서비스 → 레포지토리의 흐름 하나를 구현하고 싶을 때 모든 최상위 패키지에 접근해야 한다.

도메인형 구조

member
    - controller
    - service
    - repository
    - domain

article
    - controller
    - service
    - repository
    - domain

product
    - controller
    - service
    - repository
    - domain

 
최상단 패키지를 도메인을 기준으로 분리한다.
 
내가 정의한 도메인형 패키지 구조는 아래와 같다.
: 최상위 패키지는 도메인으로 분리하고, 하위 패키지는 계층으로 분리한다.

장점

원하는 파일을 찾아가기 용이하다.

  • 객체지향 개발자라면 코드를 분석 혹은 설계할 때 도메인에 집중할 것이다. 이 경우 도메인을 기준으로 최상위 패키지를 접근하는 방향이 매우 자연스럽다.
  • 정확한 파일명을 알지 못하는 경우, 설계와 연관 있는 도메인 패키지를 거쳐가며 파일을 찾아가기 용이하다.

하나의 기능을 구현하고 싶을 때 접근해야 하는 패키지 수가 적다.

  • 컨트롤러 → 서비스 → 레포지토리 흐름으로 진행되는 하나의 기능을 구현하고 싶을 때 하나의 도메인 패키지만 접근하면 된다.
  • API 기능별 패키지 분리가 용이하다.

도메인을 기준으로 서비스 및 API를 바라볼 확률이 높다.

  • 최상단 패키지를 도메인으로 설정할 경우, 도메인적으로 서비스를 바라볼 확률이 더욱 높다고 생각한다. 그만큼 더욱 객체지향적인 프로그래밍이 가능하다.

모듈화에 용이하다.

  • 서비스가 확장되어 프로젝트의 특정 부분을 모듈화할 때 용이하다.

단점

도메인으로 분류했을 때 애매한 위치의 객체들이 존재할 수 있다.

  • 이는 설계로 극복할 수 있는 문제라고 생각한다.

도메인 지식이 부족할 경우 개발 진행이 어려울 수 있다.

  • 도메인형 구조를 적용할 경우 프로젝트에 대한 이해도가 높아야 한다. 실무 개발을 하는 경우 전체 도메인을 파악하지 못한 채 개발을 진행할 경우가 많을텐데, 이러한 경우 도메인형 구조는 장애물이 될 수 있다.
  • ㄴ 하지만 반대로, 필요한 도메인에만 접근할테니 오히려 도메인형 구조가 편할 수도 있겠다.

나의 결론

도메인형 구조
 
모든 것엔 정답이 없고 선택하기 나름이다. 작은 프로젝트에서는 계층형 구조를, 확장 가능성이 높은 프로젝트에서는 도메인형 구조를 채택하라는 의견 또한 많았다. 그러나 현재 참여 중인 프로젝트에 한해 생각해 보았을 때, 도메인형 구조가 적절하다고 생각한다.
 
나의 경험에 의하면 도메인형 구조에서 하나의 API를 추가할 때 클래스 찾기가 매우 용이했다. 또한, 도메인형 구조의 장점은 내가 직접 체감했지만, 계층형 구조의 장점은 아직 명확하게 체감하지 못했다. 더불어 코드의 복잡도가 높아질수록 도메인형 구조의 장점이 더욱 도드라질 듯 하다.