주의 이 글은 매우 김...
YAGNI
아직 필요하지 않은 것에 대해 섣불리 구현을 해서는 아니된다는 뜻이다
난 이 원칙을... 멀티모듈 설계를 하면서 뼈저리 느낀 것 같다...
멀티 모듈이 가져다 주는 이점이 무엇인가?
이에 대해 생각하지 않고 먼저 모듈화하면 큰 이득 없이 시스템의 복잡도가 가파르게 올라가는 것을 느꼈다...
개인적으로... 아키텍처의 철학을 투영하기 위한 모듈화는 좋은 예시는 아니라고 생각해요
위 얘기는 내가 곧잘 보는 개발자가 안 좋은 모듈링에 대해 언급한 내용이다
좋은 모듈링이란 제약이 반드시 필요한 곳에 거는 것... 이라고 하였다
자세히는 언급할 수 없으나...
내가 재직하던 회사 중 한 곳의 어떤 프로젝트가 Layer 기준으로 모듈화가 되어 있었다
(아래 예시는 정확하지 않다)
예를 들면,
- SpringApplication Run 계층 (Main-Class)
- 컨트롤러가 있는 계층
- 서비스와 엔티티가 있는 계층
- Common
- 여기서 다시 Rest Client, Message Queue, Redis 등의 모듈을 다시 한 번 나눈다, 또 Library가 별도로 있다...
내가 생각했던 문제는 아래와 같다...
네비게이션이 복잡
우선 네비게이션 탭을 보면 숨이 막힌다..
구체적으로 말하면 네비게이팅이 어렵다..
작업을 하다 패키지명이 익숙해지면 패키지명을 따라서 찾고자 하는 클래스를 찾는게 쉬워진다
( 나의 경우는 (IntelliJ) option + F1, 1 단축키로 현재 클래스 기준으로 찾아나간다 )
하지만 멀티모듈의 경우 위와 같은 탐색 방식이 쉽지 않다... 오로지 점핑(cmd+B)하면서 들어가야 한다
Class 작성시, 어느 모듈에 둘 것인지 생각에 소요되는 시간이 더 든다
예를 들면 각 모듈의 책임은 무엇인지에 대해 더 생각하게 된다
Service계층은 어디에 둘 것이고, Facade of Service 는 어디에 둘 것인지...
또 클래스를 옮기다 보면, 모듈 의존성에 따라 컴파일이 되지 않는 경우도 존재했다
개념상 개발자가 생각한 의존성과 일치한다면 좋겠지만 그렇지 않을때도 존재했다
Gradle에 대한 러닝 커브
내가 맡았던 프로젝트는 2번의 depth를 가지고 있는 모듈이었다
어째선지 때로는 daemon thread가 도는 것 마냥, 실행하지 않았는데도 gradle이 혼자서 build하다가 fail뜨는 경우도 있고,
컴파일 속도가 아주 느린 때도 존재했다
최적화를 위해서는 개발자가 gradle, multi module에 대해 공부해야 했다
내가 했던 멀티 모듈 이야기
나의 경우는 결제라는 서비스를 맡아서 진행을 했었다
프로젝트를 진행하면서 "결제 서비스"안에서도 실제로 결제를 하는 부분(a)은 각별하게 보였고
난 그 패키지를 모듈화를 하고 싶은 강한 욕구가 들었다
또 즉시 결제(b)와 / 구독(c)형 서비스가 나뉘었던 부분이어서 모듈화에 대한 생각은 커졌다
그리고 어느날 날을 잡아서 한 번 시도했고, 결국 모듈화가 되었다
그러나 난 이 모듈 구조에 대해 만족하지 못했다
이유는 b, c을 묶는 하나의 모듈(d)이 필요해졌고 (이 부분은 노코멘트...)
위 b / c와 a를 이어줄 하나의 모듈(e)이 더 필요했다 (부가적인 처리가 필요한데, 이것은 a의 책임이 아니다)
그러나 이쯤 되자 모듈이 너무 많이 나와서 결국 e는 생략했다...
마지막으로 기존의 공통 모듈도 필요하다
나는 이것을 개인적으로 실패한 멀티모듈이라고 생각한다
많은 사람들이 느꼈겠지만... 우선은 모듈이 너무 많다,
네비게이션 창에서 클래쓰 찾는게 버겁고 어떤 기능이 생길때 어떤 모듈에 넣을지 고민을 더 하게 된다
또, 분명 하나의 목적을 가진 Class들이 하나의 패키지에 응집도 높게 있어야 할 것이, 모듈 dependency때문에 서로 다른 모듈에 위치할 때도 있었다 (이 부분은 자세히 기억이 나지는 않는다...)
또 위에서는 b, c로 나뉘었는데 나중에 추가 개발건으로 회원 단체로 구독하는 기능이 추가되었다 (편의상 카페 구독 기능)
이렇게 되면서 기존에 하던 모듈링의 설계 근본이 흔들리게 되었다...
즉... 변경/추가되는 요구사항에 대해 결코 더 유연하지 않았다 (되려 복잡해졌다)
이 모든 것은 처음부터 섣부른 모듈링을 하지 않았으면 일어나지 않았을 일이었다
그러면 어떤 모듈링이 좋은 모듈일까?
좋은 모듈링을 찾아서. .
동일한 Domain로직을 알고 있어야하는 서로 다른 두 App
예를 들어 이런 경우가 있다
결제라는 본질적인 기능을 하는 부분 (a) 은 별도로 존재하고
각 API 요청에 따라 응답하는 Classic한 Spring Web MVC App (b)이 있을 수 있고
주기적으로 스케줄링을 하면서 구독 결제를 하는 Schedule + Spring Batch (c)가 있을 수 있다
이때 모듈화해서 b, c가 하나의 공통된 a를 의존하면 된다
(즉 b, c 각각 a를 중복 구현하지 않게 한다)
각 마이크로서비스가 공통으로 관리하는 공통 모듈
사실 이건 모듈링을 했었을 때 장점이 아닌 MSA에서는 사실상 필수이다
예를 들어 마이크로서비스 a,b,c가 있고 a, b는 c의 내부 API가 필요하다고 하자그리고 이미 a는 c의 내부 api를 호출하기 위한 rest client를 가지고 있다모듈화를 한다면 바퀴를 재발명할 필요 없이 b또한 위 기능을 소유할 수 있다
어드민(관리자)
이건 내 의견이 아닌 제이미님의 의견이다 (사실 이 의견에 대해 공감이 아주 많이 됐다)
코어 기능이 있고 어드민의 기능이 있으면 대게의 경우 어드민은 코어를 알지만, 코어는 어드민을 모른다그리고 코어의 entity 등의 정보를 알아야 할 일이 분명 존재한다따라서 이 경우에도 어드민이 코어를 알게끔 설계하면 좋다
참고
회사를 다니면서 네카라에 재직중인 동료 친구들 보다도 Gradle에 대해 정말 친숙해진 것 같다
아래는 참고 한 자료이다
처음으로 멀티모듈을 내가 할 수 있게 만들어준 동영상
제이미님을 이때 알았다. 정말 감사합니다 제이미님... 당신은 제 첫번째 Gradle Hero에요
https://www.youtube.com/@TomGregoryTech
아예 사비로 사면서까지 공부한 사이트다.. Gradle에 대한 원론적인 이해도가 꽤 높아졌다
(그러나 현재까지도 Annotation Processing 이런 부분은 잘 모른다..)
그 외 제이미님의 Gradle 강의 영상들... 사실상 제이미님껀 다 봤다
망나니 개발자님!!
가장 공감이 많이 되는 영상이었다... 내 조숙하지 못한 개발 철학과도 많이 부합했다
지인이 있는 회사 부서인데... 사실상 잘 와닿진 않았다
https://techblog.woowahan.com/2637/
내 사수님도, 회사분도 알고 있는 전설의 권용근님 멀티모듈 설계 이야기...
후... 2depth module... 수많은 오해의 소지가 있을 수도 있다고 생각한다...
개인적으로 여기 있는 철학을 깊게 이해하지 않고 용근님의 아키텍처 그대로 받아들이는건 지양했으면 좋겠다..
'Back-end > Build (Gradle, Maven)' 카테고리의 다른 글
[Gradle Script] 복잡한 QueryDsl 설정 모아서 불러오기 (0) | 2023.12.14 |
---|---|
[Test Code, Gradle] 각 모듈에 Test Fixture를 공유하고 싶을 때 (0) | 2023.12.10 |
Gradle 다시 보기 (정리중) (0) | 2023.09.10 |
[Gradle] 기존의 프로젝트의 이름(group, artifact) 바꾸기 (0) | 2023.06.13 |
Gradle dependency 분리 하면서 생긴 문제, 해결 (0) | 2023.05.28 |
hi hello... World >< 가장 아름다운 하나의 해답이 존재한다
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!