패키지, 모듈, 서버 나누는 기준은?
패키지 vs 모듈 나누는 기준
패키지가 아니라 별도의 (멀티 모듈, 서브 모듈)로 구성했을 때의 장점은?
- ▲ 관심 분리를 통한 스파게티 코드 방지, 변경 범위 축소
- 왜 세모? 패키지만 나눠도 효과를 볼 수 있는 영역이기 때문.
- 단, 분리된 패키지 간 참조는 양방향이고, 분리된 모듈 간 참조는 단방향만 가능하다는 중요한 차이점이 있다.
- O 독립된 모듈(library)로서 여기저기서 가져다 쓸 수 있는 확장성
- O 독립된 jar로 패키징하므로 별도의 main 가지고 단독 실행 가능
- X 단독 실행을 위해 패키징 하는 경우 jar 용량 감소 -> 어차피 용량이 커지는 주 요인은 라이브러리인데, 서브 모듈도 단독 실행을 위해 라이브러리를 포함해서 패키징 한다면 용량이 드라마틱하게 절감되지는 않는다.
- ▲ 구동 속도 향상 -> 기본적으로 jvm 환경에서는 초기 구동 속도가 빠른 편은 아니지만 서브 모듈이 framework 사용하지 않는다면 단독 실행 시 1s 이내 수준으로는 만들 수 있다.
- ▲ 모듈 별로 사용하는 설정, 버전, 의존성을 다르게 관리 할 수 있다. (이는 명확한 장단점이 있다.)
- 장점 ) 모듈이 나뉘어져있지 않고 패키지만 나뉘어진 구조에서 시스템이 비대해졌다면, 의존성 버전 하나 바꿀 때 테스트 해야 하는 범위가 너무 커질 수 있음.
- 단점 ) 하단 참고
패키지가 아니라 별도의 (멀티 모듈, 서브 모듈)로 구성했을 때의 단점은?
- 비즈니스 모듈을 여러개로 분리하는 경우, 담당 개발자(또는 스쿼드/팀)가 모듈 별로 명확하게 지정되어 있어야 한다. 그렇지 않으면 오히려 개발 피로도가 더 높을 수 있다.
- 모듈 간 설정, 버전, 의존성을 모두 다르게 구성하는 경우 한 사람이 모듈을 옮겨다니면서 개발하기에는 이질감이 크기 때문이다.
- 한 사람이 전 모듈을 다 건드리기 보다는, 해당 비즈니스 모듈 담당자에게 업무 요청하는 방식으로 업무가 진행되어야 자연스럽다.
- 하지만 급하게 개발이 진행되어야 하는 경우 모듈 담당자에게 업무 요청/협의/전달 프로세스 자체가 비용이 될 수 있다.
- 이럴 때 개발자는 ‘그럴바에 내가 하지.’ 라고 생각하게 되는데 각 모듈의 이질감이 크면 속도있게 개발하기 어렵다. (당연히 있어야 할 것이 이 모듈에는 없다?)
- 애매한 오너십 관점의 문제도 있다.
- 이런 문제들 때문에, 명확하게 담당자 지정하고 타 모듈에 대한 수정사항은 해당 모듈 담당자에게 요청하는 방식으로 진행하도록 가이드라인을 세워야 한다.
- 공통 개선 사항에 대한 전파가 느리다.
- 모듈이 나뉘어져 있는 만큼 테스트 범위가 작아 개선 사항 적용이 수월하다는 것은 분명 장점이나 이에 대한 전파가 느린 것 또한 사실이다.
참고
모듈(lib) vs 서버 나누는 기준
- Monolitic vs MSA 이므로,모놀리틱을 MSA로 분리하면 장점은? 참고
- 즉 보통 사람들이 원하는 ‘분리’는 모듈 분리만으로도 충분히 얻어낼 수 있고
- 서버를 분리해서 진짜 MSA로 가야 하는 경우는 fault에 대한 robustness가 필요한 경우에 한정한다.
- MSA는 tx 제어, 배포 관리 등 여러 단점을 수반하므로 fault에 대한 robustness를 확보하는 것이 이러한 단점을 충분히 상회 할 때만 고려할만 하다.
- 특히 MSA로 역할이 나뉘어져 있는 구조에서, 어떤 데이터를 다른 서버에 REST call 해서 받아오려면 해당 서버에서 반드시 persistence->business->presentation을 거쳐 REST API를 제공해주어야 한다는 점이 낭비가 심하다.
경험적으로, 모듈과 서버는 아래와 같은 형태로 나누면 대부분의 경우 잘 들어맞는다.
- Support layer : 제일 하위의 support layer에 persistence IO, external IO를 담당하는 통합 module을 둔다.
- persistence, external을 나누지 않고 supports module 하위에서 패키지로 구분해도 된다. 다만 패키지를 나누면 모듈의 역할이 더 명확해지고, supports가 너무 비대해지지 않도록 방지하는 효과도 있다.
- Domain layer : 각 기능 집합 단위로 business module을 구성한다.
- domain model -> external dto로 변환은 여기서 수행합니다. (모듈 참조 방향 때문에 external module에서는 domain model을 몰라 domain layer에서 할 수 밖에 없습니다.)
- Application layer : 외부에서 요구하는 애플리케이션 인터페이스를 만족하기 위해, API, Admin, Batch를 각각 독립된 서버로 구성하고, 필요한 Business module을 가져다 presentation DTO로 변환하여 인터페이스한다.
This post is licensed under CC BY 4.0 by the author.