티스토리 뷰

블라드 코노노프의 "도메인 주도 설계 첫걸음"을 통해 많은 이해를 얻었는데
그의 다음 책이 나와서 기대가 컸다. 읽고 싶은 책이었던데다 마침 페이스북 책나눔 이벤트에 선정되어 재미있게 읽었다.
코드를 보지 않게 되는 AI의 시대에 이런 책이 어떤 의미를 가지게 될 지는 모르겠다. 그렇기에 더욱 소중한 책이다.
Part I. 결합
1장. 결합과 시스템 설계
결합(coupling)이란 한 요소의 변경이 다른 요소의 변경을 요구할 수 있는 관계다.
결합은 선도 악도 아니다. 피해야 할 대상이 아니라, 설계자가 다루어야 할 재료다. (14장까지 이어지는 핵심 명제)
결합이 되면 하나가 변경될 때에 다른 하나의 변경도 필요하다. 이러한 "공유된 변경"은 "공유된 수명주기", "공유된 지식" 때문이다.
- "공유된 지식"은 존 오스터하우트의 deep module을 생각나게 한다.
- 하이럼의 법칙(Hyrum's Law)도 떠오른다.
지식의 흐름과 종속성은 반대로 흐른다.
- 즉, A가 B에게 지식을 나누어 준다는 것은, 지식을 받은 B가 A에 의지하게 된다는 말이 된다.
- 의지하는 B 때문에 A는 함부로 변경을 할 수 없다.
시스템은 "목적" 달성을 위해 "구성요소" 들이 "상호작용" 하는 것이다.
- 도넬라 메도스(Donella Meadows)의 시스템 정의를 책이 인용한 것이다. 3장(상호작용)과 연결된다.
2장. 결합과 복잡성: 커네빈 Cynefin
복잡성이란 이해하기 어렵다는 것이다. 따라서 다분히 주관적이다.
- 책이 커네빈을 빌려오는 이유: complicated(선형·분석으로 풀림)와 complex(비선형·예측 불가, 분석으로 안 풀려 탐침이 필요)를 구별하기 위해서다.
커네빈 프레임워크(데이브 스노든): 의사결정을 내리는 다섯 가지 상황을 말한다. 도메인마다 행동 순서가 다르다.
- Clear(Obvious) domain: 명확하다. 인과관계가 분명하다.
- 행동 순서: 감지→분류→대응 (모범 사례).
- Complicated domain: (나에겐) 복합적인데 (이런 게 명확한) 전문가에게 물어보면 됨.
- 행동 순서: 감지→분석→대응 (분석으로 풀린다).
- 내가 잘 알게 되어도 도메인 자체가 바뀌는 건 아니지만, 나에겐 다루기 쉬워진다.
- Complex domain: 복잡해서 가설과 실험을 통해서 패턴과 규칙을 알아내야 한다.
- 행동 순서: 탐침→감지→대응.
- 개발자에겐 가장 중요한 도메인이다.
- 가설과 실험으로 패턴과 규칙을 알아내면 특정 맥락에서는 Complicated, 나아가 Clear처럼 다룰 수 있게 된다. 다만 도메인 자체가 영구적으로 바뀌는 것은 아니고, 발견한 패턴은 잠정적이다.
- Chaotic domain: 인과관계가 불명확하고 분석할 시간도 없다. 분석 대신 일단 행동(Act)해서 질서부터 잡아야 한다.
- 행동 순서: 행동→감지→대응.
- Disorder domain: 아직 위 넷 중에서 무엇인지 모른다. 최근 Cynefin 설명에서는 이 영역을 Aporetic/Confused로도 설명한다.
- 위험은 사람들이 각자 익숙한 도메인 방식으로 처리해버리는 것이다.
커네빈 프레임워크는 결정과 결과 사이의 인과관계 차이로 구분한다.
결합과의 연결: 결합 설계 결정의 대부분은 Complex 도메인에 속한다. 미리 정답을 알 수 없어 탐침·실험이 필요하다.
3장. 결합과 복잡성: 상호 작용
복잡성은 시스템의 크기와는 무관하다.
복잡성은 구성요소간의 상호작용의 특성으로 발생한다.
- 전역 복잡성을 키우는 주범이 곧 구성요소 간의 결합이다. (장 제목 "상호작용"과 연결)
전역복잡성과 지역복잡성은 함께 관리해야 한다.
- 둘 사이의 트레이드 오프, 균형을 잡아야 한다.
- 핵심: 전역과 지역 복잡성을 동시에 최소화할 수는 없다. 전역을 줄이면 복잡성이 지역으로 밀려가고, 반대도 마찬가지다.
- 그래서 "균형(balance)"이라는 이 책 전체의 주제가 여기서 처음 등장한다.
자유도를 제한할 수록 시스템은 예측이 가능하다. -> 복잡성이 낮아진다.
- 자유도(degrees of freedom): 시스템이 가질 수 있는 상태·상호작용 경우의 수.
- 원하는, 예측하고 있는 상호작용만이 가능하게 하라 -> 공유 지식을 제한하라.
- 공유 지식의 제한은 존 오스터하우트의 deep module을 생각하라.
4장. 결합과 모듈성
모듈성의 목표는 시스템의 진화를 돕는 것이다.
복잡성은 인지 부하와 관련이 된다. 알아먹을 수 있는가이다. 모듈성은 이러한 인지를 도와주는 도구이다.
모듈의 세 요소는 기능, 로직, 맥락이다.
- 기능: 공개된 인터페이스
- 로직: 내부의 동작
- 맥락: 실행환경이나 작동에 대한 가정
맥락과 가정
- 맥락과 관련한 가정과 요구사항은 기능(=공개 인터페이스)에 반영되지 않는다.
- 즉 공개 인터페이스만 봐서는 드러나지 않지만, 소비자가 모르면 잘못 사용할 수 있는 지식이다.
추상화와 정보 은닉(information hiding) -> 역시나 deep module이 생각난다.
에츠허르 데이크스트라(Edsger W. Dijkstra): 추상화의 목적은 모호한 것을 만드는 것이 아니라 절대적으로 정확할 수 있는 새로운 의미수준을 만드는 것이다. p65
모듈성은 우발적 복잡성(accidental complexity)을 제거하고 필수적(본질적) 복잡성(essential complexity)을 캡슐화(격리) 한다. p67
- 우발적/본질적 복잡성의 구분은 프레드 브룩스("No Silver Bullet")에서 온 것이다.
모듈설계의 목표는 시스템 구성요소간의 관계를 단순화하는 것이다. p71
응집력(cohesion)은 좋은 결합(coupling)이다.
- 함께 변하는 것을 같은 경계 안에 모은 상태 = 결합이 잘 배치된 것. 그래서 응집은 "좋은 결합"이다. (5장 이후와 연결)
PART II. 차원
5장. 구조적 설계의 모듈 결합
에드워드 요던과 래리 콘스탄틴이 하드웨어보다 소프트웨어 비용이 더 커지는 시점을 인지하였다.
- 구조적 설계 방법론을 제시함: 모듈식 시스템으로 해결해보자.
- 모듈화가 잘 되었는지를 보기 위해서 모듈간의 상호 관계와, 통합의 본질을 평가해보자.
- 결합이 강한 것 → 약한 것 순서. 위로 갈수록 나쁘고, 아래로 갈수록 좋다.
- 콘텐트 결합(content coupling): 한 모듈이 다른 모듈의 내부(코드나 데이터)를 직접 참조하거나 변경한다. 공개 인터페이스를 우회해 남의 속을 건드린다. 가장 강하고 위험한 결합.
- 공통 결합(common coupling): 여러 모듈이 전역 데이터(공유 상태)를 함께 읽고 쓴다. 누가 언제 그 데이터를 바꾸는지 추적할 수 없어 위험하다.
- 외부 결합(external coupling): 여러 모듈이 외부에서 강제된 공통 형식·프로토콜·장치(파일 포맷, 통신 규약, 하드웨어 인터페이스 등)에 함께 의존한다. 그 외부 규약이 바뀌면 관련 모듈이 모두 영향을 받는다.
- 제어 결합(control coupling): 한 모듈이 다른 모듈에 제어 플래그(control flag)를 넘겨 그 모듈의 내부 동작 흐름을 지시한다. 호출자가 피호출자의 내부 로직을 알고 있어야 한다 -> 추상화가 깨진다.
- 스탬프 결합(stamp coupling): 합성 데이터 구조(레코드·객체) 전체를 통째로 주고받지만, 받는 쪽은 그중 일부만 사용한다. 필요 이상의 내부 모델을 외부에 노출한다.
- 데이터 결합(data coupling): 필요한 기본(원자) 데이터만 매개변수로 명시적으로 주고받는다. 노출되는 공유 지식이 최소한이다. 가장 약하고 바람직한 결합.
결합 수준이 낮을수록 1) 다른 모듈과의 통합이 명확하고 2) 경계를 넘어서 노출되는 공유된 지식이 줄어든다. p91
6장. 공생성 Connascence
Connascence
- 함께 태어나다, 결합의 의존성 - 두 요소가 정합성을 위해 함께 맞춰져야 하는 것
- 한 요소를 바꾸면 다른 요소도 정합성을 위해 함께 바꿔야 하는 관계 (메일리어 페이지존스가 제안한 개념)
공생성을 평가하는 세 가지 속성
- 강도(strength): 약한 공생성일수록 발견·변경이 쉽다. -> 약한 쪽으로 바꾸는 것이 리팩터링.
- 정도(degree): 얽혀 있는 요소의 개수. 많을수록 변경 파급이 크다.
- 지역성(locality): 얽힌 요소가 가까이 있을수록(같은 모듈 등) 강한 공생성도 견딜 만하다.
정적 공생성(static, 컴파일 타임 / 소스 코드만 봐도 드러남) — 위로 갈수록 약함
- 이름(name): 여러 요소가 어떤 대상의 "이름"에 합의해야 한다. 변수·함수명을 바꾸면 호출부도 바꿔야 함. 가장 약한 공생성.
- 유형(type): 어떤 대상의 "유형(타입)"에 합의해야 한다. (예: 인자의 자료형)
- 의미(meaning): 특정 "값의 의미"에 합의해야 한다. (예: 0=실패/1=성공 같은 매직 넘버, 관례) -> 상수·열거형으로 약화 가능.
- 알고리즘(algorithm): 양쪽이 동일한 "알고리즘"에 합의해야 한다. (예: 송수신 양쪽의 체크섬·해시·암호화 방식)
- 위치(position): 값들의 "순서"에 합의해야 한다. (예: 위치 기반 인자) -> 명명 인자/객체로 약화 가능. 정적 공생성 중 가장 강함.
동적 공생성(dynamic, 런타임에야 드러남 — 일반적으로 정적보다 강하고 위험) — 위로 갈수록 약함
- 실행(execution): 코드의 "실행 순서"가 맞아야 한다. (예: open() 후에 read())
- 타이밍(timing): 실행의 "시점·타이밍"이 맞아야 한다. (예: 경쟁 상태, 타임아웃)
- 값(value): 여러 곳의 "값이 함께" 정합성을 유지해야 한다. (예: 사각형 네 꼭짓점, 분산된 데이터의 불변식)
- 동일(identity): 여러 요소가 "같은 하나의 인스턴스(동일한 실체)"를 참조해야 한다. 값이 같은 것으로는 부족하고, 메모리상 같은 객체·자원을 가리켜야 정합성이 유지된다. (예: 여러 스레드가 같은 락 객체를 공유해야 함, 두 컬렉션이 같은 엔티티 인스턴스를 참조해야 함) 한쪽이 복사본을 보게 되면 변경이 전파되지 않아 런타임에야 드러나는 버그가 된다. 가장 강한 공생성.
공생성은 개선이 가능한 경우도 있지만 불가능한 경우가 많다. p109
- 개선의 방향: 강한 공생성 -> 약한 공생성으로, 그리고 지역성을 높이는 쪽으로.그럴때는(약화가 불가능할 때는) 서로 가까이라도 있어야 한다. 8장에서 다루는 거리의 문제이다.
5장의 구조적 설계의 모듈 결합과 6장의 공생성은 결합의 다른 측면을 다룬다. p111
7장은 구조적 설계의 모듈 결합과 공생성의 본질에 초점을 두고 통합강도라는 통합모델을 공식화한다.
7장. 통합 강도 Strength
통합 강도(strength): 두 컴포넌트가 통합되며 공유하는 "지식의 양"을 재는 척도다. 5장(구조적 설계의 모듈 결합 = 인터페이스 유형)과 6장(공생성 = 인터페이스 복잡도)을 하나의 모델로 합친 것이다.
구조적 설계의 모듈 결합과 공생성은 꼭 연관이 있지는 않다.
- 즉, 구조적 설계의 모듈 결합 으로 봐서는 약한 결합인데, 공생성 측면에서는 강한 결합인 것이다.
- 그래서 이 둘을 통합한 통합 강도 모델을 제시한다.
상호작용은 두 가지 속성을 가진다.
- 인터페이스 유형: 예를 들어 비공개 인터페이스, 공개 인터페이스
- 구조적 설계의 모듈 결합으로 보여주기 좋다.
- 인터페이스 복잡도: 대체로 공유된 지식이 많을 수록 복잡하다.
- 공생성으로 복잡성을 반영하기 좋다.
반복해서 말하지만 구조적 설계의 모듈 결합과 공생성
- 두 방식은 항상 연관되지는 않는다.
- 명시적인 통합 인터페이스가 없어도(공유된 가정·추론된 동작 등으로) 결합이 생길 수 있다.통합 강도 4단계 (강함 -> 약함, 구조적 설계의 모듈 결합과 같거나 닮음):
- 침입 결합(intrusive coupling): 콘텐트 결합과 같다. 가장 강함.
- 기능 결합(functional coupling): 업무·기능적 지식을 공유한다. 공통·외부·제어 결합과 닮았다.
- 모델 결합(model coupling): 스탬프 결합과 닮았다.
- 계약 결합(contract coupling): 데이터 결합과 닮았다. 가장 약함.
- 강한 통합 강도일수록 가까운 거리(8장)에 두어야 한다.
8장. 거리 Distance
결합 비용 ≈ 강도 × 거리
- 거리는 결합 비용의 "증폭기"다.
- 강한 결합 × 먼 거리 = 비싸고, 약한 결합은 멀어도 견딘다.
수명주기 결합이 클수록 같이 구현, 테스트, 배포 되어야 한다.
거리 측정: 시스템 계층에서 두 컴포넌트의 "최소 공통조상"이 가까울수록 거리가 가깝다.
- 계층: 메서드 < 클래스/객체 < 모듈 < 컴포넌트 < 서비스 < 시스템
- 같은 클래스 안 = 가깝다 / 서로 다른 서비스 = 멀다.
거리는 다음에 영향을 받아 멀거나 가까워진다.
- 물리적/런타임 위치 (같은 프로세스인지, 네트워크를 건너는지)
- 조직 구조: 사회기술 설계, Conway's Law (시스템 구조는 그것을 만든 조직의 의사소통 구조를 닮는다)
- 구성 요소의 상호작용 방식
동기 통신이 비동기 통신보다 런타임 결합이 더 높다.
- 다만 비동기는 결합을 없애는 것이 아니라 수명주기/가용성 결합을 낮추는 대신 메시지 계약, eventual consistency, 재시도, 중복 처리 같은 복잡성을 새로 만든다.
공유할 지식이 적은 덩어리들로 분리해야 한다 -> Bounded Context
- Bounded Context는 단순히 작은 덩어리가 아니라 "특정 모델이 유효한 경계"다. 경계를 넘을 때는 Published Language, ACL(Anti-Corruption Layer) 같은 명시적 통합 방식을 설계해야 한다.
핵심 원칙: 거리는 결합 비용의 곱셈 인자. 강한 결합일수록 거리를 좁혀라.
9장. 변동성 Volatility
변동성(volatility) = 변경이 필요해질 가능성/변경률, 결합의 "시간" 차원이다. 결합 비용은 변경이 일어날 때만 발생한다 — 안 변하는 것엔 강한 결합도 사실상 비용이 현실화되지 않는다.
- 설계 규칙: 안정적인 것엔 강하게 결합해도 비용이 크게 현실화되지 않을 수 있다. 변동성이 크거나 변화율이 서로 다른 것끼리는 결합을 피하라.
변경은 암묵적 복잡성을 선명하게 명시적으로 만든다.
- 수정이 필요해서 보니 어디를 어떻게 고쳐야 할지 인지하기가 어렵다는 것을 알게 되면
- "이 부분 복잡했구나!" 라고 알아차리게 된다.
도메인 주도 설계(DDD, Domain Driven Design)의 subdomain 개념으로 변경률의 예측이 가능하다.
- 핵심(Core): Complex domain -> 답을 찾아내어야 한다. 변동성 높음 (자주 바뀌고 차별화 가치가 큼).
- 일반(Generic): Complicated domain. 변동성 낮음.
- 나에게는 어렵지만 이미 세상에 정답이 있다.
- 명백한 답이 있는데 애써 만들기 싫어서 이미 있는 제품을 가져다 쓰기도 한다.
- 지원(Support): Clear(Obvious) domain에 가깝다. 경쟁우위는 없고 복잡도와 변동성도 낮지만, Generic과 달리 적절한 기성품이 없어 직접 구현하는 경우가 많다.
본질적 변동성 vs 전파된 변동성
- 본질적 변동성: 서브도메인 자체의 속성이다 (Core가 자주 바뀌는 것).
- 전파된(체감) 변동성: 변동성 자체가 결합으로 "생기는" 것은 아니다. 다만 안정적인 요소가 변동성 큰 요소에 강하게 묶이면, 연쇄 변경으로 안정 요소까지 흔들린다 -> 변동성이 전파된다.
- 결합 비용 ≈ 강도 × 거리 × 변동성. 2부의 세 차원(7·8·9장)을 10장에서 종합한다.
PART III. 균형
2부에서는 결합의 강도, 공간(거리), 시간(변동성) 세 차원에서 서로에게 영향을 미치는 것을 보았다.
3부에서는 1부와 2부를 합친다. 결합을 설계도구로 바꾸어서 모듈식 소프트웨어 설계를 위해 세 차원을 결합한다.
10장 - 균형잡힌 결합이라는 개념을 다룬다.
11장 - 변화하는 시스템에서 결합의 균형을 유지하는 것을 다룬다.
12장 - 성장이라는 변화마저 수용하기
13장 - 8가지 사례 연구
14장 - 결론
10장. 결합 균형
세 가지 차원을 이야기했다. 강도(strength), 공간(거리, distance), 시간(변동성, volatility)
결합 균형(balanced coupling)이란: 강도·거리·변동성 세 차원이 정합적으로 배치되어 전역+지역 복잡성이 최소화된 상태다.
- 핵심 원칙: 강도와 거리는 반비례해야 한다. 강도가 높으면 거리를 좁히고, 강도가 낮으면 거리를 벌린다.
우리의 목표는
- 결합 강도를 최소화하는 것이 아니다.
- 구현, 진화, 유지관리가 간단한 모듈식 시스템을 설계하는 것이다.
- 변동성이 적다면 결합을 낮추기 위해 과도한 비용을 들이기보다 쉽고 빠르게 구현하는 것이 맞을 수 있다.
- 그렇지 않다면 유지보수가 쉽도록 공들여서 구현해야 한다.
다양한 방정식들 - 풀어서 문장으로 적는게 좋다 생각한다.
- 낮은 강도로 가까이 붙어 있는 것은 낮은 응집의 신호(smell)다.
- 응집력이 떨어진다.
- SRP - 오직 하나의 이유로만 변경되어야 한다는 원칙을 위반한다.
- 소수의 무관한 요소라면 영향은 작지만, 이런 요소가 늘어나면 Big Ball of Mud로 흐를 수 있다.
- 높은 강도로 멀리 떨어져 있는 것도 좋지 않다.
- 공유 지식이 먼 경계로 퍼져 전역 복잡성이 커지고, 연쇄 변경이 먼 곳까지 번지며, 유지보수 비용이 늘어난다.
- 하지만, 변동성이 낮다면 나쁜 결합의 비용이 현실화될 가능성이 낮다. 단, 낮은 변경 빈도는 진짜 안정성이 아니라 설계가 나빠서 바꾸기 어려운 상태일 수도 있다.
결합 균형(balance)이 좋으려면
- 모듈성이 좋거나(modularity), 변동성(volatility)이 낮아야 한다.
- 모듈성이 좋다는 것은
- 결합강도는 높지만 거리가 가깝거나
- 결합강도는 낮고 거리가 멀거나 한 경우이다.
11장. 결합 재조정
처음에 균형 잡힌 결합도 시스템이 진화하면 불균형해진다. 그래서 결합은 한 번 설계하고 끝이 아니라 주기적인 재조정(rebalancing)이 필요하다.
- 전술적 변경은 기본 설계구조에는 영향이 없다.
- 전략적 변경은 설계구조의 변경까지도 필요하다.
- 기능적 요구사항이 추가됨
- 비즈니스 전략이 변경됨 - 하위 도메인이 추가되거나, 하위 도메인의 유형이 바뀌는 경우
- 조직이 바뀜
- 인프라나 규제등 환경 자체가 바뀜
- 통합 강도가 바뀌는 경우: 거리를 바꿔준다. 만약 변동성이 매우 낮다면 우선순위를 낮춰도 된다.
- 변동성이 바뀌는 경우: 보통 하위 도메인이 핵심 하위 도메인으로 바뀌는 경우이며
- 거리를 줄여주거나 통합강도를 줄여주어야 한다.
- 거리가 바뀌는 경우: 예를 들어 마이크로서비스로 바꾸면 거리가 늘어난다.
- 그러면 공유되는 지식을 줄이거나, 결합의 강도를 줄인다.
결국 Balance = (Strength XOR Distance) OR NOT Volatility
- 풀어 쓰면: Strength XOR Distance = 강도와 거리 중 정확히 하나만 높다 (강↑·거리↓ 또는 강↓·거리↑) = 좋은 모듈성.
- OR NOT Volatility = 또는 변동성이 낮으면 결합 비용이 현실화될 가능성이 낮다.
- 즉 "모듈성이 좋거나, 변동성이 낮으면 균형이다" — 10장 결론과 같은 말이다.
12장. 소프트웨어 설계의 프랙탈 기하학
네트워크 기반 시스템에는 유기체, 기업, 도시, 사회구조, 인터넷 등이 있다.
- 이 장의 네트워크·스케일링 논의는 제프리 웨스트(Geoffrey West)의 스케일 법칙(저서 "Scale")에 기댄 것이다.
- 공간 채우기: 에너지가 시스템 모든 부분에 도달하게 한다.
- 불변 단말장치: 에너지는 단말장치로 전달한다. 단말장치는 일관된 크기와 특성이 유지된다.
- 최적화: 시스템은 지속적으로 진화, 효율화 된다.
네트워크 기반 시스템은 에너지 공급 네트워크라 볼 수 있다.
- 이는 소프트웨어 측면에서는 지식 공급 네트워크, 소프트웨어 설계라 볼 수 있다.
- 준선형적: 성장을 하면 에너지는 조금만 더 필요하다.
- 초선형적:
- 성장을 하면 상호작용은 팍팍 늘어난다.
- 하지만, 부정적인 측면도(생활비, 범죄율, 질병확산)도 초선형적으로 늘어난다.
갈릴레오 갈렐레이
- 덩치는 8배로 커지는데 파괴 저항력(단면)은 4배 커진다.
- 다만 더 단단하고 강한 재료, 모양의 개선으로 어느 정도 극복할 수 있다.
- 성장 한계의 돌파구가 될 수 있다.
- 사자와 고양이는 그 전체적 모양은 같으나 사자의 뼈가 훨씬 단단하다.
- 소프트웨어 설계에서는
- 재료개선(AI?)은 당장은 불가능하다.
- 하지만 모양 조절(시스템 설계) 개선은 가능하다!
에츠허르 데이크스트라 복습: 추상화의 목적은 절대적으로 정확할 수 있는 새로운 의미 수준을 만드는 것이다.
소프트웨어 시스템의 복잡성 극복은 - 프랙탈 모듈성에서 찾을 수 있다.
- 구성요소의 상호작용은 모든 추상화 수준에서 균형을 이루어야 한다.
- 따라서 균형잡힌 결합 모델은 모듈식 설계를 이끄는 자기 유사성(self-similarity) 원리가 된다.
- 모듈성은 시스템·서비스·네임스페이스·클래스·함수까지 모든 스케일에서 같은 모습으로 반복된다. 그래서 "설계"와 "아키텍처"는 본질이 다른 게 아니라 보는 스케일만 다르다.
- 주의: 한 수준의 전역 복잡성은 한 단계 위 수준에서는 지역 복잡성이 된다. 모듈을 무작정 잘게 쪼개면 복잡성이 위층으로 밀려 올라갈 뿐이다.
13장. 균형잡힌 결합의 실제
8가지 사례를 보면서 여기까지 배운 것을 정리해보자.
실전 휴리스틱: 강하게 통합된(지식을 많이 공유하는) 모듈은 거리를 줄이고, 약하게 통합된 모듈은 거리를 늘려라. 아래 8개 사례는 모두 이 원칙의 적용이다.
마이크로 서비스
- 사례1. 핵심 서브도메인이 되면서 변동성이 올라가고, 메시지 버스로 연결되어 거리도 멀어진다.
- 따라서 강도를 낮출 필요가 생긴다. 모델 결합 -> 계약 결합
- 사례2. 사례1과 유사하지만 핵심 서브도메인이 아닌 지원 서브도메인이라 모델 결합으로 충분
- 변동성이 낮으면 모델을 공유하는 비용이 크게 현실화되지 않을 수 있다. 그래서 무조건 계약 결합으로 낮추는 것이 아니라, 변동성과 거리까지 같이 보고 판단한다.
아키텍처 패턴
- 사례3. 4계층 구조의 기능 결합 -> 수직 슬라이스 아키텍처로 복잡성을 줄임. "새로운 의미수준"
- 사례4. 4계층 구조를 포트, 어댑터로 변경함. DIP
비즈니스 객체
- 사례5. Aggregate 패턴을 이용해 복잡성 감소
- Aggregate는 단순히 "동일한 트랜잭션 경계"가 아니다. 값, 불변식, 식별자 공생성이 강한 객체들을 한 경계 안에 모아 지역성을 높이는 패턴이다. 강한 공생성을 멀리 흩뜨리지 않고 가까운 경계 안에 둔다.
- 사례6. 프로젝트의 폴더 구조를 역할별 -> 기능별로 변경하여 함께 변경되는 녀석들을 한데 모으는 효과를 가져봄
- 레이어/역할별 구조는 같은 기능 변경을 여러 폴더로 흩뜨릴 수 있다. 기능별 구조는 같은 변경 이유를 가까이 두어 응집을 높인다.
메서드
- 사례7. 관련없는 메서드는 분리하고 계약 결합한다.
- 사례8. 관련없는 로직을 분리하고 계약 결합한다. 사례7과의 구분이 쉽지는 않았다.
14장. 결론
이 책의 메시지는 한 문장으로 모인다: 결합은 없애야 할 악이 아니라, 전략적으로 다루어야 할 설계 속성이다.
- 결합을 0으로 만드는 것이 목표가 아니다. 모듈 하나하나의 이론적 완벽함이 목표도 아니다.
- 목표는 시스템 전체의 유지보수 비용을 최소화하는 것 — 즉 균형이다.
세 차원을 다시 모으면:
- 강도(strength): 두 컴포넌트가 공유하는 지식의 양. (7장)
- 거리(distance): 결합된 요소가 시스템 계층에서 얼마나 떨어져 있는가. (8장)
- 변동성(volatility): 그 요소들에 변경이 필요해질 가능성/변경률은 어떤가. (9장)
균형의 규칙:
- 강도와 거리는 반비례하게 둔다 (강↑->거리↓, 강↓->거리↑).
- 변동성이 낮으면 결합이 강하고 멀어도 그 비용이 현실화되지 않는다.
- Balance = (Strength XOR Distance) OR NOT Volatility — 모듈성이 좋거나, 변동성이 낮으면 균형이다.
그리고 이 균형은 한 번에 끝나지 않는다.
- 시스템은 진화하고(11장), 설계 원칙은 시스템부터 함수까지 모든 스케일에서 프랙탈처럼 반복된다(12장).
- 그래서 균형 잡힌 결합은 한 번 적용하는 "원칙"이자 동시에 계속 이어지는 "활동"이다.
결국 좋은 설계란 결합을 제거한 설계가 아니라, 강도·거리·변동성이 어긋나지 않게 결합을 "배치"한 설계다.
'book-movie' 카테고리의 다른 글
| 2025년 후반기 독서후기 (0) | 2026.04.05 |
|---|---|
| 2025년 본 영화 후기 - 2025년 개봉 영화 아님 (0) | 2025.12.30 |
| 영화: 팬텀 스레드 (0) | 2025.11.11 |
| 영화: 리코리쉬 피자 (0) | 2025.11.03 |
| 영화: 코치 카터 - Our Deepest Fear Is... (0) | 2025.10.30 |
- Total
- Today
- Yesterday
- Gin
- postgres
- agile
- strange
- github
- 체호프
- bun
- 클린 애자일
- websocket
- MCP
- 잡학툰
- 오블완
- golang
- 티스토리챌린지
- 인텔리제이
- intellij
- gocore
- notion
- OpenAI
- clean agile
- solid
- 독서후기
- backend
- claude code
- Echo
- 영화
- ChatGPT
- API
- go
- 독서
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 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 |
