아키텍쳐

[아키텍쳐] 패키지 구조 : 계층형 VS 도메인형 어떤 것을 선택할까?

BE_성하 2023. 5. 6. 15:29
반응형

🎯 0. 들어가기 전

MVC 패턴 & 자바 기반의 콘솔 애플리케이션에서는

 

관성적으로 model(domain) & controller & view 패키지를 만들고 시작하는 경우가 대부분이었다.

 

웹 애플리케이션을 구현하면서, 설계 단계에서 관성을 버리고 패키지 구조에 대해서 고민하기로 했다.

그리고 설계하면서 설계 단계에서 패키지 구조에 대한 고민을 겪었다.

 

늘 하던 것처럼 '계층형'으로 패키지 구조를 만드는 것이 좋을까?
'도메인형' 구조가 있다는데 이 구조를 적용해볼까?


계층형과 도메인형 둘 중 하나를 선택하기 위해, 두 구조의 장단점을 비교해보자.

 

장바구니 애플리케이션이라고 가정하고, 도메인이 'Member', 'Product', 'Cart'가 있다고 하고 비교해보자.


🎯 1. 계층형 구조

controller
	⎿ ProductController
	⎿ MemberController
	⎿ CartController

service
	⎿ ProductService
	⎿ MemberService
	⎿ CartService

dao
	⎿ ProductDao
	⎿ MemberDao
	⎿ CartDao
   
domain
	⎿ Product
	⎿ Member
	⎿ Cart

 

계층형 구조는 애플리케이션에서 사용하는 계층별로 패키지를 구성하는 방식이다.

대부분이 Layered Architecture를 사용하기 때문에

Layered Architecture의 컴포넌트들 및 관련 요소들이 패키지가 되는 경우가 많다.

 

이와 같은 계층형 패키지 구조를 공부해보고 생각해보면서 느낀 장단점은 다음과 같다.

 

1-1. 계층형 구조 장단점

  • 장점
    • 1. 프로젝트 전반적인 이해도가 낮아도, 패키지 구조만 보고 전체적인 구조를 파악할 수 있다.
      • 애플리케이션의 API를 보고 흐름을 파악하고 싶다면, Controller 패키지 하나만 보고 파악할 수 있다.
      • 애플리케이션의 비즈니스 로직을 보고 싶다면, Service 패키지 하나만 보고 파악할 수 있다.
    • 2. 계층별 응집도가 높아진다. 
      • 계층별 수정이 일어날 때, 하나의 패키지만 보면 된다.

 

  • 단점
    • 1. 도메인별 응집도가 낮다. (패키지로 애플리케이션의 기능을 구분짓지 못한다)
      • 1-1. 도메인의 흐름을 파악하기 힘들다.
        • Product 도메인의 흐름을 보고 싶을 때, 모든 계층 패키지를 봐야한다.
        • 하나의 패키지안에 여러 도메인(상품, 장바구니, 사용자)들이 섞여 있다.
      • 1-2. 도메인과 관련된 스펙 & 기능이 변경되었을 때, 변경 범위가 크다.
        • Product에 대한 변경점이 있을 때, 여러 패키지에서 변경이 일어난다. 
    • 2. 유스케이스(사용자의 행위) 표현이 어렵다.
      • 규모가 커지면, 유스케이스별로 클래스를 분리할 때가 있다.
      • ex : 상품 등록 유스 케이스 -> RegisterProductService
      • 하지만, 계층형에서는 계층으로 패키지가 묶이기 때문에 위와 같이 네이밍해서 분리하기 어렵다.
    • 3. 규모가 커지면 하나의 패키지 안에 여러 클래스들이 모여서 구분이 어려워진다. 

 


🎯 2. 도메인형 구조

product
	⎿ controller
	⎿ service
	⎿ dao
	⎿ dto

member
	⎿ controller
	⎿ service
	⎿ dao
	⎿ dto
    
cart
	⎿ controller
	⎿ service
	⎿ dao
	⎿ dto

 

도메인형 구조는 도메인을 기준으로 패키지를 나눈 구조이다.

 

이와 같은 도메인형 패키지 구조를 공부해보고 생각해보면서 느낀 장단점은 다음과 같다.

 

2-1. 도메인형 구조 장단점

  • 장점
    • 1. 도메인별 응집도가 높아진다. 
      • 1-1. 도메인의 흐름을 파악하기 쉽다.
        • Product 도메인의 흐름을 보고 싶을 때, Product 패키지 하나만 보면 된다.
      • 1-2. 도메인과 관련된 스펙 & 기능이 변경되었을 때, 변경 범위가 적다.
        • Product에 대한 변경점이 있을 때, Product 패키지만 변경이 일어난다.
    • 2. 유스케이스별로 세분화해서 표현이 가능하다.
      • ex : 상품 등록 유스 케이스 -> RegisterProductService
      • ex : 상품 검색 유스 케이스 -> SearchProductService
      • 도메인별로 패키지가 나뉘기 때문에 product 패키지에서 위와 같은 네이밍으로 분리할 수 있다.

 

  • 단점
    • 애플리케이션의 전반적인 흐름을 한눈에 파악하기가 어렵다.
      • 흐름을 파악하기 위해 여러 패키지를 왔다갔다 해야할 가능성이 높다.
    • 개발자의 관점에 따라 어느 패키지에 둘지 애매한 클래스들이 존재한다.
      • Welcome 페이지를 맵핑하는 컨트롤러일 때, 어느 도메인 패키지에 위치할지 개발자에 따라 다를 수 있다.
      • 자신이 예상하는 패키지와 다를 때, 해당 클래스를 찾기가 어렵다.

🎯 3. 결론 - 계층형 VS 도메인형 어느 구조를 선택할까?

위에서 계층형과 도메인형 패키지 구조와 장단점을 살펴봤다.

 

그렇다면, 어떤 패키지 구조를 선택해야할까?

 

장단점을 비교해보면서 '무조건적으로 좋은 것, 정답은 없다'라고 느꼈다!

 

프로젝트 및 애플리케이션 규모 및 상황에 따라 장단점을 비교해서 선택하는 것이 좋을 것 같다고 생각했다.

 

 

그렇다면, 어떤 기준으로 선택을 할까?

 

일단 프로젝트 경험이 많이 없는 지금 내가 정한 기준은 다음과 같다.

(아직 프로젝트 경험이 많이 없어서 추후에 경험해보면서 기준이 바뀔 수도 있을 것 같다!)

* 계층형 구조 선택
  - 규모가 작고, 도메인이 적은 경우
    - 계층형 패키지 안에 클래스들이 구분이 안될만큼 많아질 경우가 적다.
    - 애플리케이션 흐름 및 가독성이 도메인형보다 좋다.
    - 유스케이스별로 클래스를 분리하는 경우가 적다.
    - 도메인의 변경이 일어나도, 규모가 작고 도메인이 적은만큼 변경 범위가 그렇게 크지 않을 것이다.
    
    
* 도메인형 구조 선택
  - 규모가 크고, 도메인이 많은 경우
    - 규모가 크고 도메인이 많은 만큼 도메인의 응집도가 높은 것이 중요할 것이다.
    - 규모가 큰 만큼 유스케이스별로 클래스를 분리하는 경우가 있을 수 있다.

 

계층형, 도메인형 패키지 구조의 예시에서 사용한 애플리케이션에서는

위의 기준에 따라 '계층형' 구조를 선택했다.

 

더 자세한 이유로는 '도메인형' 구조가 가진 단점이 너무 크게 느껴졌다.

'도메인형'으로 설계했을 때 가독성이 '계층형' 구조에 비해 너무 안 좋았고,

어느 패키지에 들어가야할지 모르는 클래스가 있었어서 '계층형' 구조를 선택하게 되었다.

 

이처럼, 기준을 정하고 trade-off를 적당히 파악하면서

매번 애플리케이션 설계 시마다 적절한 패키지 구조를 정하는 것이 좋다고 느끼게 되었다!


Reference

https://ahnheejong.name/articles/package-structure-with-the-principal-of-locality-in-mind/

 

지역성의 원칙을 고려한 패키지 구조: 기능별로 나누기

보다 효율적이고 견고한 패키지 구조에 대한 고민

ahnheejong.name

https://cheese10yun.github.io/spring-guide-directory/

 

Spring Guide - Directory - Yun Blog | 기술 블로그

Spring Guide - Directory - Yun Blog | 기술 블로그

cheese10yun.github.io

https://jaime-note.tistory.com/411

 

클린 아키텍처: 패키지 구성

이 포스팅은 만들면서 배우는 클린 아키텍처를 읽고 작성하였습니다. Overview 코드를 구성하는 몇 가지 방법과 헥사고날 아키텍처를 표현하는 패키지 구조를 소개합니다. 프로젝트를 처음 생성

jaime-note.tistory.com

 

반응형