항상 프로젝트를 시작할 때 항상 패키지 구조에 대한 고민을 하게 됩니다. 적어도 저는 그런 것 같습니다. 팀 프로젝트에선 어떤 패키지 구조를 사용할지 논의를 하다 과열되어 시간을 허비한 적도 있습니다.
이처럼 자주 사용되는 개념이라면 적어도 한 번은 공부해 보는 게 좋을 것 같다는 생각에 이번 글을 작성합니다.
정의
패키지 구조란 파일들을 논리적으로 구분하고 조직화하는 방식을 말합니다.
즉, 파일을 아무 데나 두는 것이 아니라, 어떠한 기준(계층, 도메인, 기능...)에 따라 묶어놓은 구조를 뜻합니다.
장점
도서관에 갔다고 상상해 보겠습니다.
1. 가독성
만약 책이 여기저기 널브러져 있다면 원하는 책을 찾기 쉽지 않을 것입니다. 하지만 책들이 전부 책장에 꽂혀 있다면? 더 수월하게 책을 찾을 수 있습니다.
더해서, 만약 이 도서관이 책을 가나다순(기준)으로 정리되어 있다는 사실을 미리 알고 있다면, 훨씬 빠르게 원하는 책을 찾을 수 있습니다.
2. 확장성 & 유지 보수성
정리가 잘 되어 있다면 새로운 책을 추가할 때도 알맞은 위치를 바로 찾을 수 있습니다.
3. 협업 효율성
도서관에 새로운 직원이 들어왔을 때, 정리된 책의 배치를 알려준다면 어려움 없이 업무에 합류할 수 있을 것입니다.
3가지 패키지 구조
헥사고날 아키텍처, 클린 아키텍처.. 등등과 같은 다양한 패키지 구조가 있지만 이 글에서는 대표적인 패키지 구조인 계층형, 도메인형, 기능형 이렇게 3가지 패키지 구조만 간단히 소개하도록 하겠습니다.
1. 계층형 패키지 구조
com.example.app
├── controller (웹 요청 처리)
├── service (비즈니스 로직)
├── repository (데이터 접근)
...
계층을 기준으로 파일들을 분리한 구조입니다.
전체 프로젝트 계층으로 나눴기 때문에 프로젝트가 어떻게 구성되어 있는지 쉽게 파악할 수 있습니다. 또한 계층이 전담하는 역할을 알고 있다면 어떤 파일이 어떤 역할을 하는지도 쉽게 알 수 있습니다.
하지만 계층의 수는 고정되어 있기 때문에 프로젝트가 커지면 커질수록 각 계층에 포함되는 파일들이 포화되어 파일 구분이 어려워진다는 단점이 있습니다.
2. 도메인형 패키지 구조
com.example.app
├── user (사용자 도메인)
│ ├── UserController
│ ├── UserService
│ └── UserRepository
├── order (주문 도메인)
│ ├── OrderController
│ └── OrderService
...
도메인을 기준으로 파일들을 분리한 구조입니다.
계층형 구조와 달리 도메인은 프로젝트와 비례해서 증가하기 때문에 많은 파일이 한 곳에 몰리는 문제가 발생하지 않습니다. 또한 묶여있는 파일들은 오직 하나의 도메인과 관련된 파일들이므로 '지역성의 원칙'을 잘 지키는 구조라고 할 수 있습니다.
하지만 프로젝트 전체 구조를 파악하기는 어렵습니다.
3. 기능형 패키지 구조
기능별로 파일들을 분리한 구조입니다.
하나의 기능을 수정할 때 필요한 파일들이 한 곳에 모여 있기 때문에, 도메인형 구조와 마찬가지로 '지역성의 원칙'을 잘 지키는 구조라고 할 수 있습니다. 또한 기능과 연관된 모든 파일이 같은 곳에 있기 때문에 기능을 수정하거나 삭제하거나, 기능을 다른 프로젝트에 재사용하기도 편리합니다.
하지만 도메인형 패키지 구조와 마찬가지로 프로젝트 전체 구성을 파악하기는 어렵습니다.
개인적인 생각
사람들은 저마다 선호하는 정리 기준을 가지고 있습니다. 그 기준을 바탕으로 책상 위에 놓인 필기구를 정리하고, 유튜브 재생목록을 만들기도 합니다.
패키지 구조 또한 크게 다르지 않으며, 취향이 있을 뿐 완벽한 패키지 구조란 없다고 생각합니다. 그렇기에 패키지 구조를 정형화하는 것은 무의미하다고 생각합니다. 프로텍트마다 팀원도, 상황도 다른데 하나의 정답만 존재할 수는 없기 때문입니다.
특히 “이 구조는 반드시 이렇게 나눠야 한다!”라는 생각은 소통할 여지를 줄이고 마찰로 이어질 수 있습니다. 저는 실제로 그런 경험을 했고, 후회로 남았습니다.
참고자료
[Spring boot] 디렉터리 패키지 구조의 선택
Spring Boot 개발 중 학습이 필요한 내용을 정리하고,트러블 슈팅 과정을 기록하는 포스팅입니다.
velog.io
[Spring boot] 디렉터리 패키지 구조의 선택
Spring Boot 개발 중 학습이 필요한 내용을 정리하고,트러블 슈팅 과정을 기록하는 포스팅입니다.
velog.io
Clean Architecture Packaging Strategy
TL; DR Clean Architecture 를 구성할 때에도 Package by Feature 방식을 고려해봅시다. What is Package? (일반적으로) 사람들은 잘 정돈된 책상을 보면 기분이 좋아집니다. 물론 사람에 따라 책상을 보는 것 자체
tech.buzzvil.com
굿프렌즈팀의 DDD 기반 기능별 패키지 구조 적용기
이 글은 우리FISA 클라우드 서비스 개발자 굿프렌즈팀 `팬시`가 작성했습니다. 굿프렌즈팀은 프로젝트를 진행하면서 어떠한 패키지를 구성하면 좋을지 고민했습니다. 보통 패키지를 구조를 나누
goodfriends-team.tistory.com
'CS' 카테고리의 다른 글
| DI의 종류와 Constructor DI가 권장되는 이유 (4) | 2025.06.14 |
|---|---|
| Java final 키워드 (1) | 2025.06.12 |
| 실수계산 오차와 부동소수점 ( feat. IEEE 754 표준 ) 3부 (0) | 2025.05.21 |
| 실수계산 오차와 부동소수점 ( feat. IEEE 754 표준 ) 2부 (0) | 2025.05.16 |
| URI vs URL vs URN (0) | 2025.04.14 |