규모가 있는 프로젝트를 진행하다 보면 직면하게 되는 문제가 있다. 바로 내가 맡은 기능의 코드를 찾기가 까다롭다는 것이다. 수많은 Service
중 UserService
를 찾고, Domain
패키지에서 User
를 찾는 것은 꽤 불편한 일이다. 이것들은 모두 계층형 구조만 쓰고 있기에 벌어지는 일이다.
프로젝트의 코드 구조를 어떻게 조직하느냐는 생산성과 유지보수성에 큰 영향을 미친다. 일반적으로 많이 사용되는 두 가지 코드 구조 방식이 있는데, 바로 계층형 구조(Layered Architecture)와 도메인형 구조(Domain-Driven Design, DDD)이다.
계층형 구조는 애플리케이션을 기능별로 나누어 각 기능이 독립적으로 동작하도록 하는 방식이다. 예를 들어 Controller
는 모두 Controller
패키지에 넣고, Service
는 모두 Service
패키지에 넣는 식이다.
com.example.projectname
├── controller
├── service
├── repository
├── domain
├── dto
├── config
└── exception
도메인형 구조는 도메인에 초점을 맞추어 코드를 구성하는 방식이다. 이 방식에서는 관련된 기능들을 도메인 단위로 그룹화한다. 예를 들어, 사용자 관련 클래스는 user
패키지에, 제품 관련 클래스는 product
패키지에 넣는 식이다.
com.example.projectname
├── user
│ ├── controller
│ ├── service
│ ├── repository
│ ├── domain
│ ├── dto
│ └── exception
├── product
│ ├── controller
│ ├── service
│ ├── repository
│ ├── domain
│ ├── dto
│ └── exception
└── config
user
controller/UserController.java
service/UserService.java
repository/UserRepository.java
domain/User.java
dto/UserDTO.java
exception/UserNotFoundException.java
product
controller/ProductController.java
service/ProductService.java
repository/ProductRepository.java
domain/Product.java
dto/ProductDTO.java
exception/ProductNotFoundException.java
구분 | 레이어형 구조 | 도메인형 구조 |
---|---|---|
구조 | 기능별로 패키지를 나눔 | 도메인별로 패키지를 나눔 |
장점 | 각 레이어별로 역할이 명확 | 각 도메인별로 모듈화가 잘 되어 있음 |
코드 중복이 줄어듦 | 각 도메인의 독립성 유지 | |
단점 | 대규모 프로젝트에서 패키지가 복잡해짐 | 코드 중복이 발생할 수 있음 |
도메인 간의 의존성이 높아질 수 있음 | 도메인 간의 의존성 관리가 어려울 수 있음 | |
예시 | controller , service , repository 등 | user , product 등 도메인 단위로 나눔 |
스프링 부트 프로젝트의 디렉터리 구조는 프로젝트의 유지보수성과 확장성에 중요한 역할을 한다. 레이어형 구조와 도메인형 구조는 각각의 장단점이 있으며, 프로젝트의 규모와 요구 사항에 따라 적절한 구조를 선택하는 것이 중요하다.
따라서 혼자 미니 프로젝트를 개발하는 경우, 레이어형 구조를 선택하는 편이 좋고 대규모 프로젝트를 협업으로 진행하는 경우 도메인형 구조가 유리할 수 있다.