|
| 1 | +## Chapter 08: 재사용 패턴 |
| 2 | + |
| 3 | +### 개요 |
| 4 | + |
| 5 | +- 가급적 개발자들은 반복적인 코드를 줄이고 재사용성을 높인다 |
| 6 | +- 모놀리식의 경우 라이브러리 혹은 모듈 임포트만으로 재사용이 쉽기 때문에 문제가 되지 않음 |
| 7 | +- 허나 분산 아키텍처에서는 공유 코드를 작성할 때 고려해야 하는 부분이 많음 |
| 8 | + |
| 9 | +--- |
| 10 | + |
| 11 | +### 코드 복제 |
| 12 | + |
| 13 | +- 공유 코드 (여러 서비스에서 두루두루 쓰이는 코드) 를 단순히 서비스 레포지토리 안에 복사하는 행위 |
| 14 | +- 정적인 코드, 일회성 코드 등 변경사항이 극히 적고, 버그의 가능성이 낮은 코드의 경우 오히려 복사 붙여넣기가 빛을 발할 때도 있다 |
| 15 | + - 그렇지 않을 경우, 여러 군데에 단순 복사한 코드들을 다같이 관리해주어야 하기 때문에 여간 번거로운 것이 아님 |
| 16 | + - 예를 들어, 한 곳에 복사한 코드에서 버그가 발생했다면? 나머지는? |
| 17 | + - 가능한 한 변경될 여지가 적은 정적 유틸리티 클래스에 적합하다 |
| 18 | + |
| 19 | +--- |
| 20 | + |
| 21 | +### 공유 라이브러리 |
| 22 | + |
| 23 | +- 컴파일 타임에 바인딩되는 라이브러리를 통해 여러 서비스가 한 라이브러리를 바라보게 하는 기법 |
| 24 | + - 컴파일 타임에 라이브러리 코드들이 서비스들에 공유된다 |
| 25 | + - 공유 코드의 변경 빈도가 (코드 복사가 필요할 때처럼 변경 빈도가 아예 없는 수준은 아니지만) 꽤 낮을 경우 적합한 기법 |
| 26 | +- 라이브러리의 트레이드오프는 라이브러리의 크기가 좌우한다 |
| 27 | + - 단위가 큰 공유 라이브러리 한두개만 사용할 경우, 하나의 통짜 라이브러리만 업데이트하고 관리하면 되기 때문에 각 서비스별 디펜던시 관리가 수월하다 (디펜던시 적음) |
| 28 | + - 허나 라이브러리 안의 코드가 조금씩 변경되면, 라이브러리 전체에 영향을 미치므로, 라이브러리 업데이트와 함께 테스트 범위가 매우 커진다 (변경 관리 어려움) |
| 29 | + - 단위가 작은 라이브러리 여러 개를 사용할 경우, 한 라이브러리에서 발생한 변경점은 다른 라이브러리나 코드에 큰 영향을 미치지 않으므로 유지보수가 수월하다 (변경 관리 쉬움) |
| 30 | + - 단 서비스 - 라이브러리 간 의존도가 복잡해지며 (한 서비스가 하나의 라이브러리만 바라보는 것이 아니므로) 이것이 나중에는 큰 진흙덩어리 하나가 될 가능성이 있다 (디펜던시 많음) |
| 31 | +- 서비스가 커지면 트레이드오프에서 오는 부작용도 커지므로 가급적 거대 라이브러리보단 작은 라이브러리 여러 개를 사용하여 디펜던시를 포기하고 변경 관리에서 이점을 얻는 것이 낫다 |
| 32 | + - 정적인 성격의 기능들을 라이브러리로 분리할 경우 의외로 디펜던시에 영향도 적음 |
| 33 | +- 라이브러리 사용 시, 무조건 버저닝을 해야 호환성에서 이점을 얻을 수 있다 |
| 34 | + - 라이브러리의 버전을 올리거나, 구 버전을 레거시화 하여 지원하지 않게끔 하는 것도 전략이다 |
| 35 | + - 잘 변경될 일 없는 정적인 라이브러리는 비교적 적은 범위의 버전 안에서 관리 |
| 36 | + - 자주 변경되는 라이브러리는 여러 버전으로 관리 |
| 37 | + - 변경점이 잦은 라이브러리를 적은 버전만으로 관리할 경우, 라이브러리 업데이트 시 영향받는 모든 서비스들을 추적하고 배포 및 테스트 해야 하므로 불필요한 공수가 늘어난다 |
| 38 | + - 특정 범위를 벗어나는 옛 버전은 가능한 한 구식화하여 불필요한 관리를 줄여야 함 |
| 39 | + - 덩치 큰 라이브러리 사용 지양 |
| 40 | + |
| 41 | +--- |
| 42 | + |
| 43 | +### 공유 서비스 |
| 44 | + |
| 45 | +- 공유 라이브러리보다 한 사이즈 큰 기법 |
| 46 | + - 공용 기능을 묶어 하나의 서비스로 두고, 다른 서비스들이 이를 바라보게 하는 기법 |
| 47 | + - 다른 기법 (복제, 라이브러리화) 와 같은 코드 상속보다는, 여러 기능을 조합하여 큰 기능을 만드는 형태 |
| 48 | +- 기능을 공유 서비스로 분리할 경우, 해당 기능이 변경되어도 다른 서비스까지 재배포할 일이 없어 간편하다 |
| 49 | + - 단, 해당 기능이 '잘' 변경되었을 경우에만 한정 |
| 50 | +- 공유 기능의 변경 빈도가 높을 경우, 그리고 다양한 프로그래밍 언어가 공존하는 환경에 적합 |
| 51 | +- 공유 서비스로 분리한 기능에서 버그가 발생할 경우, 나머지 서비스도 무너지는 참사가 발생할 수 있음 (내고장성 이슈) |
| 52 | + - 공유 서비스의 경우 컴파일타임 전까지는 버그 판독이 어렵다 |
| 53 | + - 런타임에 서비스들끼리 유기적으로 엮이고 나서야 버그 여부를 알게 됨 |
| 54 | + - 적절한 버저닝을 통해 리스크를 완화시킬 수 있음 |
| 55 | +- 코드만 가져다 쓰는 다른 두 기법과 다르게, 공유 서비스는 결국 기능을 위해 또다른 서비스를 호출해야 하므로 성능 이슈가 생길 수밖에 없다 |
| 56 | +- 공유 서비스를 사용하는 다른 서비스의 사이즈에 따라, 공유 서비스 크기를 적절하게 관리해야 한다 |
| 57 | + |
| 58 | +--- |
| 59 | + |
| 60 | +### 사이드카와 서비스 메시 |
| 61 | + |
| 62 | +- 사이드카 패턴: 육각형 아키텍처 (도메인을 중앙에, 포트와 어댑터를 통해 다른 계층과 커플링) 기반 |
| 63 | + - 인프라 로직과 도메인 로직을 분리하는 것에 의의를 둠 |
| 64 | + - 오토바이 옆에 붙어있는 사이드카에서 명칭을 따옴 |
| 65 | +- 한 서비스 내에 분리가능한 파트 (도메인 관심사와 조금 떨어져있는 파트), 타 서비스와 엮이는 커플링에 해당하는 파트를 사이드카로 분리 |
| 66 | + - 타 서비스와 사이드카 파트를 통해 기능을 연결할 수 있다 |
| 67 | + - 사이드카끼리 맞물려 형성한 일종의 그물망을 메시라고 함 (그물망이 영어로 메시임) |
| 68 | + |
| 69 | +``` |
| 70 | +논의점 및 느낀점: 유독 공유 서비스 기법에 대한 단점이 길게 서술된 느낌이 든다. 반면 사이드카 기법은 구축이 복잡한 편이다~ 정도 외엔 장점 위주로 적혀 있는데, 다른 분들은 해당 두 파트를 읽으면서 비슷한 생각을 하셨을지 유독 궁금한 챕터였다. |
| 71 | +
|
| 72 | +개인적으론 초기 구축에 들어가는 에너지 (?) 면에선 공유 서비스 분리가 훨씬 간단해 보이고, 사이드카 기법은 서비스에 대한 충분한 지식이 뒷받침되어야 한다는 추가적인 단점이 있을 듯하다 |
| 73 | +``` |
0 commit comments