[잔디일기] 패키지 구조에 대한 고민 - 적용결과

아래의 '[잔디일기] 패키지 구조에 대한 고민'에 대한 글로부터 이어지는 글입니다.

 

[잔디일기] 패키지 구조에 대한 고민

잔디 일기 서비스의 경우 간단한 서비스였기 때문에 1차 기능 구현 기간까지는 비교적 수월하게 진행을 해 왔으나,1. 초반에 팀원 분들과 서로 상의하지 않고 각자 구현했던 패키지 구조로 인해

yeseul-dev.tistory.com

 

해당 글을 토대로 패키지 구조 변경을 시도 했습니다.

하지만 구조 변경을 하면서 필요한 패키지들이 보였고, 기존 예정이었던 아래와 같은 구조에서 조금 변경하게 되었습니다.

# 기존 계획
⎿ grassdiary
    ⎿ global
    	⎿ auth
    	⎿ util
    	⎿ common 
        	⎿ request
        	⎿ response
    	⎿ config
        	⎿ properties
    	⎿ error		# 예외 핸들링
        	⎿ ExceptionHandeler.java
        	⎿ exception
        		⎿ ErrorCode.java
        		⎿ EntityNotFoundException.java
	        	⎿ InvalidValueException.java
	        	⎿ ...
    ⎿ domain 			# base 패키지를 제외한 도메인별 동일 구조
        ⎿ base 		# 도메인 엔티티가 공통적으로 사용할 클래스
    	⎿ member
        	⎿ controller
        	⎿ domain 	# 도메인 엔티티에 대한 클래스
        	⎿ dao
        	⎿ service
        	⎿ exception
        	⎿ dto
        ⎿ diary
        ⎿ color
        ⎿ reward

 

수정 결과

⎿ grassdiary
    ⎿ global
    	⎿ auth
    	⎿ util
        	⎿ date
        	⎿ file
    	⎿ system
        	⎿ date
        		⎿ controller
        		⎿ service
    	⎿ common 
        	⎿ error
        		⎿ exception
        		⎿ ExceptionHandler.java
        	⎿ request
        	⎿ response
    	⎿ config
        	⎿ properties
        	⎿ XXXConfig
    ⎿ domain 			# base 패키지를 제외한 도메인별 동일 구조
        ⎿ base 		# 도메인 엔티티가 공통적으로 사용할 클래스
    	⎿ member
        	⎿ controller
        	⎿ entity 	# 도메인 엔티티에 대한 클래스
	        	⎿ Entity.java
	        	⎿ DAO.java
        	⎿ service
        	⎿ exception
        	⎿ dto
        ⎿ diary
        ⎿ color
        ⎿ image # 이미지 서버 추가로 도메인 추가
        ⎿ reward

 

 

1. 날짜 값을 반환하는 클래스는 util로, 컨트롤러와 DTO는 system 패키지에 넣어 주었습니다.

왜 system 패키지에 위치 시켰을까요?

처음 패키지 구조를 구성할 때는 컨트롤러와 DTO 클래스는 global.common 패키지에 위치 시켰습니다.

 

util 패키지:

목적: 공통적으로 사용되는 유틸리티 클래스와 함수들을 모아놓는 곳

내용: 날짜 처리, 문자열 처리, 파일 처리 특정 비즈니스 로직과 무관하게 여러 곳에서 재사용 있는 기능들을 포함한다.

예시: DateUtil, StringUtil, FileUtil 등.

 

common 패키지:

목적: 애플리케이션 전반에 걸쳐 공통적으로 사용되는 클래스와 설정들을 모아놓는 곳

내용: 공통 데이터 모델, 예외 처리 클래스, 인터셉터, 공통적으로 사용되는 상수 등.

예시: CommonResponse, GlobalExceptionHandler, CommonConstants 등.

 

설명에 따르면, common 클래스의 경우 애플리케이션 전반에 걸쳐 공통적으로 사용이 되는 클래스를 모아둔 곳입니다.

하지만 저희가 사용하는 로직에서 date와 관련된 클래스의 경우 클라이언트에서 필요할 때 가져다 쓰는 컨트롤러와 DTO 뿐입니다.

 

그래서 이와 관련된 엔티티는 딱히 없고 global한 값이니 global.system이라는 패키지를 만들어 해당 패키지 안에 date 내용을 넣었습니다.

 

2. image 패키지를 생성 했습니다.

일기를 작성할 때 이미지를 추가할 수 있도록 업데이트 중에 있기 때문에 새로운 패키지가 필요하다고 판단 했습니다.

 

3. 현재는 order 패키지가 없지만, 생성하면 좋을 것 같습니다.

MemberPurchasedColor.java 라는 엔티티 클래스가 있습니다.

현재는 멤버가 받은 리워드 포인트로 살 수 있는 아이템이 없지만, 추후 업데이트 되는 것을 가정한다면 order 패키지로 옮기는 것이 나을 것 같습니다.

하지만 해당 기능을 업데이트하는 것은 후순위이기 때문에 기존에 위치한 member 패키지 아래에 그대로 두었습니다.

 


실제 프로젝트 패키지 구조(스크린샷)

패키지 구조가 엄청 간단해졌습니다!



 

해당 패키지 구조의 목적은 한 가지의 기능을 추가하거나 수정할 때 비교적 좁은 곳에서의 수정만 이뤄지게 하기 위함입니다.

 

이렇게 패키지를 위치 시키니 도메인과 관련된 클래스와 아닌 클래스를 구분할 수 있게 되었습니다.

클래스를 보고 구분을 하다 보니, 도메인과 관련이 없는 메서드가 해당 클래스 내에 위치하고 있어 리팩토링이 필요한 부분이 꽤나 보여 좋았습니다. (왜 이게 여기있지?)

 

도메인 주도 개발을 하는 중, 어떤 방법으로 클래스와 패키지를 나누었어야 했는지 알게 된 계기가 되었습니다.