지금까지 spring mvc, jpa, security, swagger, redis와 같은 내용을 공부할때 공부한 내용을 

기존에 진행하던 스터디 일정 관리 프로젝트에 적용해보는 방식으로 공부했다.

 

그런데 이렇게 하나의 프로젝트에 여러 기능들을 넣고 적용하다보니, 패키지 구조가 복잡해지고 알아보기 힘들어졌다.

한눈에 봐도 난잡해보이는 패키지 구조다.

처음엔 controller, service, repository, domain, dto, exception만 존재했지만,

앞서 말한 여러 기능들을 추가하며 지금과 같은 구조를 띄게 되었다.

 

이러한 패키지 구조는 필요한 파일을 찾기 힘들게 하며, 여러 패키지의 코드가 얽혀있어

controller - service - repository로 이어지는 계층형 아키텍쳐의 의존관계 설정을 힘들게 해 순환참조와 같은 문제를 일으켰다.

 

그렇다면 적절한 패키지 구조는 무엇일까?

https://www.inflearn.com/questions/16046/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8F%B4%EB%8D%94-%EA%B5%AC%EC%A1%B0%EC%99%80-%EA%B0%95%EC%9D%98-%EC%9D%BC%EC%A0%95%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC-%EC%A7%88%EB%AC%B8%EC%9D%B4-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4

 

프로젝트 폴더 구조와 강의 일정에 관하여 질문이 있습니다. - 인프런

1. 실무에서 프로젝트 구현시 보통 폴더 구조를 어떤식으로 하시나요?프로젝트를 하는데 폴더 구조를 어떻게 해야 좋을지 궁금합니다. 강의와 같이 api 패키지를 하나 만들고 Controller 클래스 안

www.inflearn.com

 

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

 

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

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

cheese10yun.github.io

 

패키지 구조에 대해 고민하며 구글링을 하면 가장 많이 찾을 수 있는 좋은 자료 2개를 가져와봤다.

 

계층형 vs 도메인형?

계층형 구조

project
    ├── controller
    │   ├── UserController.java
    │   ├── ScheduleController.java
    │   └── WorkspaceController.java
    ├── domain
    │   ├── User.java
    │   ├── Schedule.java
    │   └── Workspace.java
    ├── dto
    ├── exception
    ├── repository
    └── service

계층형 구조는 각 계층을 기준으로 패키지를 구성하며 다음과 같은 장단점을 가진다.

  • 처읍 보는 사람도 프로젝트의 구조를 파악하기 쉽다.
  • 프로젝트 규모가 커질수록 하나의 디렉토리에 파일들이 모이게 되고 구조를 파악하기 힘들어진다.

 

도메인형 구조

project
    ├── user
    │   ├── controller
    │   ├── domain    
    │   ├── repository
    │   └── service
    ├── schedule
    │   ├── controller
    │   ├── domain    
    │   ├── repository
    │   └── service
    └── workspace
        ├── controller
        ├── domain    
        ├── repository
        └── service

도메인형 구조는 도메인을 기준으로 패키지를 구성하며 다음과 같은 장단점을 가진다.

  • 하나의 도메인에 관련된 코드들이 응집해있어 모듈 단위 프로젝트 분리가 쉽다.
  • 프로젝트에 대한 이해도가 낮을 경우 패키지 구조를 파악하기 위한 난이도가 높아진다.

우리 프로젝트에 더 적합한 패키지 구조는 무엇일까?

나는 고민끝에 계층형 구조를 선택하기로 했다.

 

왜 계층형 구조인가요?

분명히 요즘 유행하는 프로젝트 구조는 도메인형이 맞다.

위에서 언급한 글도 그렇고, 대부분의 블로그와 깃허브 소스코드를 살펴봐도

최근엔 도메인형으로 패키지 구조를 설계하는 경우가 상당히 많다.

 

하지만 은탄환은 없다.

유행하는 구조가 있다고 해서 반드시 따라갈 필요는 없고, 내 프로젝트에 맞는 패키지 구조를 선택하는 것이 더 좋다고 생각했다.

 

이번 프로젝트의 도메인은 User, Workspace, Schedule, DevLog 4개가 전부였다.

비즈니스 로직 또한 크게 복잡하지 않아서 모든 도메인이 하나의 Controller, Service를 사용한다.

(Sprint data jpa를 사용해 Repository는 여러개를 사용했다.)

project
    ├── user
    │   ├── controller
    │   │   	└── UserController.java
    │   ├── domain
    │   │   	└── User.java
    │   ├── repository
    │   └── service
    │   │   	└── UserService.java
    ├── schedule
    │   └── ...
    ├── devLog
    │   └── ...
    └── workspace
        └── ...

도메인형을 사용하면 위의 구조처럼 대부분의 디렉토리에 디렉토리당 하나의 파일만 들어가게 된다.

나는 이게 배보다 배꼽이 큰거 아닌가? 라고 생각했다.

 

도메인이 많지 않으며, 도메인별로 연관관계는 많아 서로 참조할 일이 많은데

디렉토리만 저렇게 많이 만들면 파일 찾기만 힘들지 아닐까? 라고 생각했다.

 

그러나 이렇게 계층형 구조로 패키지 구조를 설정하기 위해선 우리 프로젝트에 몇가지 문제점이 존재했다,

 

1. 특정 계층에 속하지 않는 패키지들

기존의 패키지 중 Interceptor, filter, argumentResolver, sucurity 와 같은 패키지들은 특정 계층에 넣기 힘들다.

그렇다고 이 패키지들을 그대로 놔두면 디렉토리가 너무 많아지고 가독성에 좋지 않다.

이러한 패키지들은 특정 계층에 속하지 않고 또 여러 도메인과 계층에서 사용되므로 common 패키지를 구성하여 따로 관리했다.

 

2. 어플리케이션과 다른 정책을 가지는 admin 패키지

이번 어플리케이션은 REST API를 제공하기 위해 만들었다.

(그래서 controller 패키지의 이름도 사실 api라고 붙이는 것이 더 적절해보인다)

 

그러나 admin 페이지 정도는 백엔드에서 직접 만드는 것이 더 간단하기 때문에

타임리프를 사용해 admin 페이지를 구현하는 admin 패키지를 만들었다.

이 어드민 페이지는 5개의 컨트롤러를 가지고 있으며 기존 api의 컨트롤러와는 속성이 많이 다르다.

 

그래서 admin 패키지만 도메인 계층처럼 따로 분리하기로 결정했다.

 

결과

project
    ├── admin
    │   ├── controller
    │   └── dto
    ├── common
    │   ├── auth
    │   ├── config
    │   └── interceptor
    ├── controller
    ├── domain
    ├── dto
    ├── exception
    ├── repository
    └── service

다음과 같은 나름 깔끔한 패키지 구조를 갖게 되었다.

디렉토리 1개당 2~5개 정도의 파일을 가져 가독성도 충분하다.

 

물론 도메인형도 아니고 계층형도 아니고 이게 뭐냐 라고 불편해할 수도 있다.

사실 완벽한 방법은 없는것 같다.

프로젝트에 요구사항이 더 추가되고, 도메인이 늘어나거나 파일이 늘어나면 도메인형으로 다시 바꿀 가능성도 있다.

 

중요한건 상황에 맞는 구조를 선택하는것이 아닐까 싶다.

+ Recent posts