[프로젝트 일기 3/9] 패키지 구조는 어떻게 가져가야 할까?

Updated:

프로젝트 환경설정을 진행하면서 패키지 구성을 어떻게 하는게 좋을지 고민이 되었다. 🤔

패키지 구성은 크게 계층형과 도메인형이 있는데 각각의 구조와 장단점을 간단하게 알아보자면 다음과 같다.

계층 구조

└── src
      ├── main
         ├── java
            └── com
                └── example
                    └── demo
                        ├── DemoApplication.java
                        ├── config
                        ├── controller
                        ├── dao
                        ├── domain
                        ├── exception
                        └── service
         └── resources
             └── application.properties

장점 👍

  • 프로젝트의 전체적인 구조를 빠르게 파악 가능.
  • 각 패키지간 cyclic dependency 발생 가능성 적음.
  • 중복 제거 용이

단점 👎

  • 디렉터리에 클래스가 너무 많이 모임.
  • 기능 단위 분리가 어려움.

도메인 구조

└── src
      ├── main
         ├── java
            └── com
                └── example
                    └── demo
                        ├── DemoApplication.java
                        ├── coupon
                           ├── controller
                           ├── domain
                           ├── exception
                           ├── repository
                           └── service
                        ├── member
                           ├── controller
                           ├── domain
                           ├── exception
                           ├── repository
                           └── service
                        └── order
                            ├── controller
                            ├── domain
                            ├── exception
                            ├── repository
                            └── service
         └── resources
             └── application.properties

장점 👍

  • 관련된 코드들이 응집.
  • 기능 단위 분리에 유리.

단점 👎

  • 프로젝트 이해도가 낮으면 구조파악 어려움.
  • 중복 코드 발생 가능.
  • 패키지간에 cyclic dependency 발생 가능성 높음.

다른 프로젝트는 어떤 구조일까? 👀

이런 고민이 생길때면 다른 사람의 코드를 자주 참고하는 편이다.

먼저 스프링 공식 예제 프로젝트인 petclinic 을 살펴보았다.

└── petclinic
	├── model
	|	├── BaseEntity.java
	|	├── NamedEntity.java
	|	└── Person.java
	|
	├── owner
	|	├── Owner.java
	|	├── OwnerController.java
	|	├── OwnerRepository.java
	|       ├── ...
	|
	|
	├── system
	├── vet
	├── PetClinicApplication.java

petclinic 패키지 구조 또한 ower 패키지 내에 도메인, 컨트롤러, 레포지토리로 구성된 도메인형 구조였다.

이 외에도 여러 사람들의 프로젝트를 살펴보았고 대부분이 도메인 구조를 체택해서 사용하고 있었다.

결론

결론부터 말하자면 도메인형으로 패키지 구성을 가져는것으로 정했다.

과거에는 monolithic 하게 개발하는 추세였고 계층간의 역할을 구분하는게 더 중요시 생각되던 아키텍쳐 기반으로 계발이 이루어졌기 때문에 계층형이 더 적합했을 것이라 생각하지만 최근에 MSA(Micro Service Architecture)에 대한 논의도 많이 되고있고, 각 기능별로 응집력을 높인다는 관점에서 기능 단위로 나눈 도메인 구조가 더 적합하다고 생각된다.

MSA로 도메인 별로 서로 다른 팀이 분할을 해서 작업을 한다 해도 패키지 별로 나누어서 작업을 할수 있기 때문에 더 편리할듯 하다.

도메인 구조는 도메인 별로 기능이 응집되어 있고 좀더 객체지향적 설계와 ORM에 적합하다고 생각한다.

뿐만 아니라 패키지가 도메인 별로 관련 코드가 응집되어 있기 때문에 원하는 클래스를 찾기가 쉬워졌다.

── src
      ├── main
         ├── java
              └── promisor
                    └── promisor
                        ├── PromisorApplication.java
                        ├── domain
                           ├── group
                              ├── api
                              ├── application
                              ├── dao
                              ├── domain
                              ├── dto
                              └── exception
                           ├── member
                              ├── api
                              ├── application
                              ├── dao
                              ├── domain
                              ├── dto
                              └── exception
                           └── model
                               ├── Address.java
                               ├── Email.java
                               └── Name.java
                        ├── global
                           ├── common
                              ├── request
                              └── resonse
                           ├── config
                              ├── SwaggerConfig.java
                              ├── properties
                              ├── resttemplate
                              └── security
                           ├── error
                              ├── ErrorResponse.java
                              ├── GlobalExceptionHandler.java
                              └── exception
                           └── util
                        └── infra
                            ├── email
                            └── 
                                ├── 
                                ├── 
                                └── d
         └── resources
             ├── application-dev.yml
             ├── application-local.yml
             ├── application-prod.yml
             └── application.yml

프로젝트 참고 자료 📚

Categories:

Updated:

Leave a comment