diff --git a/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/03.md b/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/03.md new file mode 100644 index 00000000..6e44ec14 --- /dev/null +++ b/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/03.md @@ -0,0 +1,58 @@ +## Chapter 04: 아키텍처 분해 + +### 개요 + +- 컴포넌트 기반 분해 + - 어플리케이션의 논리적 구성 요소 단위 (컴포넌트 단위) 를 추출하고 이를 이용하여 아키텍처를 구성 + - 코드베이스가 컴포넌트 단위로 구성되어 있어 분해 가능할 경우 이쪽 선택 +- 전술적 분기 + - 애플리케이션 사본을 복사하고 필요없는 부분을 깎아내며 구성 + - 코드베이스 분해 불가능할 경우 (엉망일 경우) 이쪽이 적절한 선택 +- 도구를 이용하여 코드베이스의 특성을 파악하고 구조를 판별 + +### 추상도와 불안정도 + +- 코드베이스의 균형을 나타내는 척도 +- 추상도 + - 구현 대비 추상화가 이뤄진 정도 + - 추상 요소와 구상 요소의 개수로 측정한다 +- 불안정도 + - 코드베이스가 불안정한 정도 + - 커플링 (구심, 원심) 이 높을 경우 불안정도가 올라감 + - 컴포넌트끼리 강하게 엮여 있어 하나를 수정하면 다른 컴포넌트에 영향을 미칠 확률이 높다는 뜻 + +![image03-01](./images/03_01.png) + +- 메인 시퀀스로부터의 거리 + - 추상도와 불안정도 사이의 이상적인 관계 + - x절편, y절편, 기울기 1의 직선 + - 이 선에 가까울수록 이상적이다 (컴포넌트 균형이 적절하다) +- 메인 시퀀스로부터의 거리 그래프 기준으로 + - 오른쪽 위로 치우친 부분은 추상화가 과도한 (쓸모없는) 구역 + - 사용이 어려움 + - 왼쪽 아래로 치우친 부분은 추상화가 없다시피한 (고통스러운) 구역 + - 취약하고 관리가 어려움 + +``` +논의점: 추상도, 불안정도, 거리 등의 요소가 굉장히 수학적인 요소로 보이는데, 개발에는 정답이 없듯이 컴포넌트가 추상적인지, 불안정한지 여부를 판가름하는 기준도 매우 모호할 듯하다. 추상 클래스 등 명확하게 추상적인 요소가 없는 경우 이러한 수치들을 계산하고, 아키텍처 구성에 참고할 만한 자료로 삼는 것이 과연 가능할까 의문이 든다. +``` + +### 컴포넌트 기반 분해 + +- 컴포넌트 단위의 폴더구조 및 파일로 디렉터리를 구성 및 각 코드 분리 +- 모놀리식을 분산 아키텍처로 마이그레이션할 때 도움이 된다 + +### 전술적 분기 + +- 진흙잡탕 아키텍처를 다듬을 때, 추출보다는 필요없는 것을 떼어내는 것에 중점 +- 서로간의 의존성 때문에 추출에 한계가 있는 경우 +- A팀, B팀이 서로 각각 코드베이스 사본을 복사한 후, 각자의 팀에 필요한 코드만 남기고 나머지를 삭제하는 기법 + - 이렇게 하면 각 파트별 큰 구조는 유지하면서 모놀리식 구조를 덩어리로 쪼갤 수 있다 +- 분해보다 상대적으로 쉽지만 모놀리스 코드의 흔적이 계속 남아있을 가능성이 있다 +- 개발자가 노력을 기울이지 않으면, 조금 더 가벼워졌을 뿐인 (코드 용량만 줄어든) 진흙덩어리가 될 수도 있음 + +``` +느낀점?: 마침 아주 최근에 큰 덩어리의 진흙 코드를 서비스별로 분기하는 작업을 진행했는데, 그 과정에서 덩어리를 서비스별로 복사하고 그중 필요없는 코드를 지우고 공통화할 수 있는 코드만 분리하여 덩어리를 경량화한 적이 있었음. 전술적 분기 파트를 읽으면서 해당 작업 생각이 났다. (내가 진행한 작업이 어찌보면 전술적 분기구나? 하는) + +난이도는 확실히 처음부터 작정하고 분리를 시도하는 것보다 간단한 편이고 시간도 많이 걸리지 않았지만, 덩어리 A를 분리하고 나서 덩어리 B를 작업하는 도중에 덩어리 A에 미처 덜어내지 못한 찌꺼기를 발견하는 등 코드 깎아내기에 어느 정도 익숙하지 않으면 실수하기가 쉬운 듯 하다. A 덩어리는 C, D, E 서비스를 분기할 때까지도 찌꺼기와 공통화가 덜된 요소들이 계속 발견되어 추가작업을 진행해야 했다.. 눈물.. +``` diff --git a/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/04.md b/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/04.md new file mode 100644 index 00000000..606a7227 --- /dev/null +++ b/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/04.md @@ -0,0 +1,83 @@ +## Chapter 05: 컴포넌트 기반 분해 패턴 + +### 개요 + +![04_01](./images/04_01.png) + +1. 컴포넌트 식별 및 사이징 + - 나눌 컴포넌트의 크기를 결정 +2. 공통 도메인을 갖는 컴포넌트 수집 + - 중복 가능성이 있는 로직 통합 +3. 컴포넌트 눌러펴기 + - 도메인, 서브도메인, 컴포넌트를 정리 +4. 컴포넌트 디펜던시 결정 + - 디펜던시를 다듬어 마이그레이션 실현가능성 및 작업량 결정 +5. 컴포넌트 도메인 생성 + - 컴포넌트를 애플리케이션 내부의 논리적 도메인들로 그룹핑 및 리팩터링 +6. 도메인 서비스 생성 + - 모놀리식 애플리케이션의 논리 도메인을 개별 배포된 도메인 서비스들로 이동 + - 모놀리식을 서비스 단위로 쪼개기 + +### 컴포넌트 식별 및 사이징 + +- 애플리케이션을 구성하는 컴포넌트를 식별하여 크기를 조절 +- 너무 크거나 너무 작은 컴포넌트를 찾아내는 작업 + - 큰 컴포넌트의 경우 다른 컴포넌트들과의 결합도가 높을 가능성이 높다 +- 컴포넌트 크기를 결정하는 지표 + - 문장 수 (조건문, 분기문 등, 세미콜론으로 구분) + - 파일 수 + - 이러한 수치들을 이용하여 컴포넌트의 비중 계산 + - 컴포넌트 사이즈를 일정하게 유지하기 위해 피트니스 함수나 툴을 쓰면 좋다 + - 어떤 컴포넌트가 추가되고 삭제되었는지 알려주는 툴 + - 코드베이스에서 차지하는 비중을 나타내고 임계치를 벗어나지 않게끔 돕는 툴 + - 컴포넌트가 코드베이스 컴포넌트들의 크기 평균치보다 크지 않게 알려주는 툴 + - etc + +- 사이즈는 애플리케이션 전반적으로 일정한 크기 유지가 필요함 +- 컴포넌트 식별하기 + - 컨벤션을 유지한 적절한 이름 + - 네임스페이스 (컴포넌트가 위치한 디렉터리 또는 패키지 등) + - 컴포넌트 비중 > 문장 수, 파일 수 + +- 예시에서 성한은 리포팅 컴포넌트의 비중이 지나치게 크다는 것을 발견하여 이를 적절한 세부 단위로 쪼개는 것으로 컴포넌트 크기를 고르게 만들었음 + +### 공통 도메인을 갖는 컴포넌트 수집 + +- 공통 도메인 로직을 발굴하여 단일 컴포넌트로 중앙화하는 패턴 +- 여러 서비스에서 같이 사용되는 기능을 통합해 두면, 추후 중복 서비스를 쉽게 제거할 수 있다 +- 이름이나 네임스페이스를 이용하여 구분 +- 공통 도메인 로직 통합 전후의 커플링 (결합도) 을 계산하면 컴포넌트의 비중 및 통합 필요성 여부 판단에 도움이 된다 + +### 컴포넌트 눌러펴기 + +- A 컴포넌트가 B 컴포넌트를 기반으로 생성되고, B 컴포넌트가 C 컴포넌트를 기반으로 생성되는 등 + - 예시: 설문 (ss.survey) 하위에 설문 템플릿 (ss.survey.templates) 이 존재하는 경우 + - 설문 (ss.survey) 클래스와 직접적으로 연관된 컴포넌트는 없음 + - ss.survey.templates 컴포넌트를 ss.survey 로 옮겨 합치거나, ss.survey 기능을 분해하여 ss.survey.create, ss.survey.process 등으로 확장하여 루트 네임스페이스로 만드는 방법이 있다 + - 이때 ss.survey의 공통 클래스는 고아 클래스이므로, ss.survey 하위에 있는 컴포넌트들이 가져다 쓰는 ss.survey.template 를 추가하면 된다 + +- 디렉터리 상에 리프 노드만 존재하게끔 평평하게 누르는 작업 +- 고아 클래스를 없애는 작업 + - 고아 클래스: 어떠한 컴포넌트와도 연관되지 않은, 루트 네임스페이스에 속하는 클래스 + +### 컴포넌트 디펜던시 결정 + +![dependencies](./images/04_02.png) + +- 컴포넌트 간의 커플링 (데이터가 오가는 구간) 을 분석하여, 디펜던시가 어떤 양상을 보이는지 결정하는 패턴 +- 모놀리식 어플리케이션을 분해했을 때 각 서비스간 어떠한 연관 (의존성) 을 가질지 분석하는 과정 +- 위 이미지의 경우, 컴포넌트 간의 디펜던시가 너무 커서 사실상 컴포넌트 분해가 어렵고, 다시 코딩하는게 나은 수준 +- 미리 컴포넌트 간의 결합도를 파악하는 것은 각 디펜던시를 리팩터링하고 서비스 단위로 분해하는 데에 큰 도움을 준다 +- 피트니스 함수로는 디펜던시 개수에 제한을 두거나 특정 컴포넌트간 디펜던시를 갖지 않게 막을 수 있다 + +### 컴포넌트 도메인 생성 + +- 서로 관련된 기능들을 수행하는 컴포넌트들을 그룹핑하여 도메인을 식별하는 것은 결국 서비스 기반 아키텍처에서 각 서비스의 대상을 결정하는 과정이다 +- 네임스페이스 노드로 도메인을 표현하면 좋다 +- 예를 들어, 과금 관련 컴포넌트와 고객 프로필 관련 컴포넌트를 `고객` 이라는 더 큰 도메인으로 묶어서 체계화할 수 있다 + +### 도메인 서비스 생성 + +- 컴포넌트 도메인 구조를 잘 잡았다면, 이를 각 도메인 서비스로 옮겨서 서비스 기반 아키텍처를 구축한다 +- 도메인 서비스 마이그레이션 전에 컴포넌트들을 그 도메인의 특성에 맞게 리팩터링한 후 마이그레이션을 하는 것이 좋다 + - 그렇지 않으면 한 도메인이 다른 도메인에 꾸겨들어가야 하는 불상사가 발생 diff --git a/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/images/03_01.png b/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/images/03_01.png new file mode 100644 index 00000000..9efd1ec2 Binary files /dev/null and b/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/images/03_01.png differ diff --git a/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/images/04_01.png b/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/images/04_01.png new file mode 100644 index 00000000..c94c0d39 Binary files /dev/null and b/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/images/04_01.png differ diff --git a/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/images/04_02.png b/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/images/04_02.png new file mode 100644 index 00000000..eb6bcbf0 Binary files /dev/null and b/2026/Fundamentals_of_Software_Architecture_2nd_Edition/chichoon/images/04_02.png differ