종류
- 
어떤 스타일의 팀에, 어느정도 규모의 팀에 어울릴지. 무조건 좋은건 없음. 
- 
누구는 복합적으로 사용한다고 말할수도 있을텐데, 정확히 어떻게 나눠서 얘기할수있는가? 
Monolith
Multorepo
- 
독자적인 repository로 소스를 관리하는 방법 
- 
git을 사용할 경우 독자적인 repository를 하나의 repository 안에서 submodule로 구성/관리할 수 있음 
- 
Polyrepo 구조라고도 불림 
- 
각 프로젝트는 높은 자율성을 가지며, 독자적인 개발, 린트, 테스트, 빌드, 게시, 배포 파이프라인을 갖게 됨 
- 
팀의 자율성 때문에 선호하기도 함 
- 
단점 - 
번거로운 프로젝트 생성 
- 
패키지의 중복 코드 가능성 
- 
관리 포인트 증가 
- 
일관성 없는 개발자 경험 
- 
다른 패키지의 변경 사항 파악 
- 
교차 리포지토리의 리팩터링 비용 
 
- 
- 
일부 단점에 대해서 IntelliJ를 통해서 어느정도 해소 가능하나, 개발자 개개인의 도구 숙련도가 필요함 
Monorepo
?
- 
monorepo + 1 git repo - 
어떤 관심사로 repo를 모을 것인가? 
 
- 
- 
multi git repo (monolithic?) - 
git submodules + multi git repo 
- 
intellij 에서 multi git repo에 대한 지원 활용 
 
- 
- 
작은 토이 프로젝트가 아닌 이상 프로젝트는 점차 커지고 효율적인 관리를 위해 소스코드를 분리하게 됨 
- 
Spring Framework 기반에서 주로 아래와 같은 빌드 툴과 기능을 활용함 - 
Gradle: multi-project 활용 
- 
Maven: Module 활용 
 
- 
- 
프로젝트가 단위별로 나눠지는 것은 당연한 일이라고 할 수 있지만, 어떤 관점으로 어떻게 나누냐는 팀마다 다를 수 있음 
Core
- 
재활용이 가능한 중복 코드를 Core라는 패키지, 모듈, 프로젝트 혹은 저장소에 모아두는 구조 
- 
코어 기반 구조는 Common, Parent 등으로도 불려짐 
장점
- 
중복 코드 제거 
- 
중복 코드를 제거할 수 있다. 
- 
코드 재활용에 수월하다. 
- 
수정해야하는 비지니스를 한번에 관리할 수 있다. 
단점
- 
크기 - 
시간이 지남에 따라 점점 비대해진다. 팀원이 많다면 더 빠른 속도로 증가한다. 
 
- 
- 
접근성 - 
누구나 비지니스 로직을 넣기 쉬워진다. 이는 다양한 
 
- 
- 
컴포넌트를 분리하기 어려워진다(싫어진다) 
- 
빌드시간이 길어진다 (테스트 포함) 
- 
사이드 이펙트 
- 
런타임 오버헤드 - 
쓰지도 않는 빈이 같이 올라간다. 부팅시간 올라감 
 
- 
- 
빅브라더 
- 
스파게티 코드 - 
한곳만 수정하면 되니 장점으로 말하는 사람도 있을테지만, 장점보다 단점이 더 크지 않은가? 
 
- 
- 
의존성 덩어리 
그럼?
- 
무엇을 코어에 두어야 하나 
- 
코어라는 이름을 버릴까? 
- 
enum들이 적당 
- 
어노테이션, 각 코드(상수) 
- 
유틸, 익셉션, 엔티티, … - 
엔티티가 비지니스를 가졌다고 생각든다면 DB 테이블에 대해 추상화가 안된게 아닐까 
 
- 
- 
client 
Multi Module Project
특징
- 
API 클라이언트들이 각 모듈로 나눠져있을 때, build.gradle.kt만으로 어떤 클라이언트들을 사용하지는지 명확하게 알 수 있음
- 
API 클라이언트들이 각 모듈로 나눠져있을 때, 새로운 클라이언트 의존성을 추가할 때 gradle 리로드가 필요함(개발 속도) 
- 
너무 잘게 나눠져있을 경우, 새로운 코드짤 때 어디에 넣어야할지 고민하게 됨 
- 
불가피한 코드 중복이 발생하게 됨 - 
e.g. DB저장용 Country, API 인터페이스용 Country, VO 개념의 Country 
 
- 
관리 방법
- 
빌드 도구를 활용한 서브 모듈 - 
js 진영에서는 monorepo(lerna), workspace(npm) 
- 
multi-project(gradle) 
 
- 
- 
Git Repository 별로 분리 - 
Git을 활용한 submodule 활용 가능 
- 
굳이 submodule repo를 만들지 않아도 IDEA 툴에서 원활하게 개발할 수 있도록 지원함 
 
- 
중복 코드에 대한 새로운 관점
- 
리팩토링 책에서 중복 코드에 대해서 메서드 올리기를 통해 부모로 옮기라고 말하지만, 여기서 부모는 core 모듈을 말하는 것이 아닌 상위 호출자를 말하는거라 생각한다. 
- 
"부모로 옮긴다."에만 포커싱을 갖게 되면 결국 core가 만들어진다. 
- 
상위로 올리고, 유틸리티를 만들고, 부모가 커지는 느낌을 받는다면 다시 한번 전체를 살펴보자. (나무가 아닌 숲을 보기) 
- 
계층을 갖게되면 다른 고민/문제점이 발생함. 
- 
유연함을 생각하자 - 
ApiClient 들은 서킷브레이커랑 WebClient를 주입 받을 것인가?
- 
사용하는 곳마다 ReadTimeout, ConnectionTimeout이 다를텐데? 
- 
이와 같이 다를 경우가 얼마나 있을 것인지. 우선 통합해서 사용하다가 추후에 타임아웃 시간과 BaseUrl 정도만 주입받아도 충분할 듯 
 
- 
모든 중복을 제거할 순 없다.
코드 중복은 죄악이 아니다.
Core-Less?
- 
어느정도 중복은 허용하자. 이젠 강력한 기능을 지닌 IDEA에서 중복코드 제거는 껌. 
- 
분리가 필요한 시기에 옮겨도 충분. 하지만 무지성으로 코드 중복 제거, 메서드 옮기기 하지 않고 중복을 유지하는게 더 낫다면 유지. 
- 
빌드 속도, 어플리케이션 실행 속도에 중점? 
- 
디펜던시는 모두 API를 호출하게끔? 이건 결국 API가 코어가 되는게 아닐까? - 
"그럼 무슨 문제가 있는가? 요즘 MSA 기반에서 무슨 문제인가?" 
 
- 
Etc
- 
그럼 언제 구조를 변경할 것인가? core → core-less or multomodule, … 
- 
빌드 캐시 
개인고민
팀원 모두 기술 수준, 이해도가 높다면 걱정 x 어떻게 얼만큼 제한할 수 있는지? 최소한의 제약을?? 패키지로?? 도메인으로?(이게 젤 어려움), 의존성으로?
References
- 
https://kwonnam.pe.kr/wiki/web/%EC%8B%A0%EA%B7%9C%EC%84%9C%EB%B9%84%EC%8A%A4 
- 
https://kwonnam.pe.kr/wiki/web/신규서비스 절대 하지 말아야 할 일 : ecommerce-core 혹은 ecommerce-common 형태의 여러 도메인 비즈니스 로직을 모아둔 공통 모듈을 만들면 절대로 안 된다.