Step 15. 선택의 기술 — 트레이드오프와 결정의 기록

만화로 보는 요약 — 먼저 읽어보세요
정답표 대신 도메인 복잡도·조직 규모·수명과 무결성의 세 다이얼을 읽고, 되돌리기 비싼 선택과 그 대가를 ADR로 남긴다.
면접 실전 질문: ① 아키텍처 선택의 세 다이얼은 무엇인가? ② ADR에는 어떤 항목을 남기는가? ③ 왜 결정의 나쁜 결과도 기록해야 하는가?
이 장의 질문: 도구는 전부 손에 있다. 이제 실제 상황 앞에서 — 무엇을 근거로 고르고, 그 선택을 어떻게 남기는가? 그리고 이 책의 첫 문장이었던 정의는, 열다섯 장을 지나 어떤 모습으로 돌아오는가?
1. 정답표는 없다 — 그러나 판단 절차는 있다
독자가 이 장에 기대할 법한 것부터 부수자: “팀 규모 N명, 트래픽 M이면 아키텍처 X”라는 표는 존재할 수 없다. 제1법칙(Step 04)이 그 이유다 — 모든 선택이 트레이드오프라면, 정답은 상황(무엇을 포기할 수 있는가)의 함수이지 입력값의 함수가 아니다. 목표는 최선(best)이 아니라 가장 덜 나쁜(least worst) 것이었다.
정답표 대신 이 장이 주는 것은 세 가지다: 상황을 읽는 다이얼(2절), 결정을 남기는 문법(3절), 그리고 결정 앞에서 도는 체크리스트(4절).
2. 세 개의 다이얼 — 상황을 읽는 법
아키텍처 선택에 들어가는 변수는 수십 개지만, 이 책의 여정에서 반복해 등장한 지배 변수는 셋이다. 각 다이얼은 특정 품질 속성의 몸값을 올린다.
다이얼 1: 도메인 복잡도. 규칙과 불변식이 얼마나 많고 자주 자라는가.
- 낮음 → 빈혈 모델 + 트랜잭션 스크립트가 정직함이다(Step 06). 레이어드로 충분하다.
- 높음 → 리치 도메인 모델(Step 07)과 그것을 지킬 벽(헥사고날, Step 08)의 할증이 정당화된다. 갈림길의 교차점은 지나고서야 보이므로(Step 07), 복잡도가 자라는 추세라면 그것이 신호다.
다이얼 2: 조직 규모. 몇 팀이 이 시스템을 함께 바꾸는가.
- 한 팀 → 모놀리스. 경계는 패키지로 충분하다.
- 여러 팀 → 컨텍스트·모듈·팀의 삼중 정렬(Step 09)이 사활 문제가 된다. 모듈러 모놀리스(Step 10)가 기본값, 배포 조율이 실측된 병목이 된 모듈만 서비스로 — 분산의 물리학(Step 10)은 그때 지불해도 늦지 않다.
다이얼 3: 수명과 무결성 요구. 얼마나 오래 살고, 틀리면 얼마나 비싼가.
- 짧고 관대함(프로토타입, 캠페인) → 구조 투자 최소화. 진흙이어도 좋다 — 버릴 것이라면(Step 05의 Throwaway Code — 단, 정말 버려진다는 보장이 있을 때만).
- 길고 엄격함(금융, 원장) → 무결성이 가용성에 앞서고(Step 04, 11), 불변 원장·대사·적합도 함수(Step 11, 12)가 선택이 아니라 요건이 된다.
다이얼을 읽는 순서도 여정이 가르쳐준 대로다: 안에서 밖으로. 도메인 모델의 형태(다이얼 1)를 먼저, 경계와 소유권(다이얼 2)을 다음에, 배포 토폴로지는 마지막에 — 그리고 가능하면 미룬 채로(최종 책임 시점, Step 12). 유행의 순서는 흔히 그 반대라는 점(“일단 마이크로서비스로”)이, 유행이 자주 실패하는 이유다.
3. 결정의 문법 — ADR
무엇을 고를지 알았다면, 남는 일은 남기는 것이다. Step 01에서 Perry & Wolf가 아키텍처의 세 요소에 rationale(근거)을 넣었을 때부터 예약된 결말이다 — 근거가 아키텍처의 일부라면, 근거를 저장할 형식이 필요하다.
Michael Nygard가 2011년에 제안한 **아키텍처 결정 기록(ADR, Architecture Decision Record)**이 그 형식이다. 마크다운 한 장, 다섯 항목:
# ADR-007: 정산 원장은 추가 전용으로 하고 수정은 역분개로만 한다
## Status
Accepted (2026-07-16)
## Context
정산 금액 정정 요구가 월 평균 12건. 현재는 UPDATE로 원본을 덮어쓰고 있어
감사 시점에 "왜 이 값인가"를 재구성할 수 없다. 금융 규제상 변경 이력의
완전성이 요구된다. 팀은 이벤트 소싱 전면 도입을 검토했으나 운영 경험이 없다.
## Decision
원장 테이블을 추가 전용(append-only)으로 전환한다. 정정은 역분개 행 추가로만
한다. 이벤트 소싱 전면 도입은 하지 않는다 — 원장 하나에만 그 규율을 적용한다.
## Consequences
+ 모든 잔액이 행의 합으로 재구성 가능 — 감사 추적 완결.
+ 정정의 이력이 업무 언어(역분개)로 남는다.
- 조회가 집계 쿼리가 된다 — 잔액 스냅숏 테이블(읽기 모델)이 추가로 필요하다.
- UPDATE에 익숙한 팀의 학습 비용. 기존 정정 화면 재작업 2주.구조가 곧 규율이다. Context는 “그때 우리가 알던 것”을 박제한다 — 6개월 뒤 이 결정이 이상해 보일 때, 틀린 것이 결정이었는지 상황이 바뀐 것인지 구별하게 해주는 유일한 자료다. Consequences에는 나쁜 것을 반드시 적는다 — Step 04의 교환 명세서(“X를 얻으려 Y를 지불했다”)가 문서 형식이 된 것이며, 지불 항목이 없는 ADR은 트레이드오프를 아직 못 본 것이다(제1법칙의 따름정리). 그리고 ADR은 불변이다: 결정이 바뀌면 수정하지 않고 새 ADR이 이전 것을 대체(supersede)한다 — 원장과 역분개, 낯익은 규율이다.
보관 위치는 코드 옆(docs/adr/)이다. 위키가 아니라 저장소에 — 결정은 코드와 함께 버전되고, 코드 리뷰의 대상이 되고, 코드를 읽는 사람의 손이 닿는 곳에 있어야 하므로. 무엇이 ADR감인가의 판별은 이 책의 정의가 해준다: 되돌리기 비싼 결정이면 쓴다. 라이브러리 하나 고르는 것은 대개 아니고, 원장의 저장 모델은 확실히 그렇다.
4. 결정 앞의 체크리스트 — 열다섯 장의 압축
실제 결정 앞에서 도는 질문 여덟 개. 각각이 이 책의 장 하나씩을 등에 업고 있다.
- 이것은 되돌리기 비싼 결정인가? (Step 01) — 아니라면 그냥 하라. 체크리스트는 여기서 끝이다. 모든 결정을 아키텍처 결정으로 만드는 것 자체가 병이다.
- 미룰 수 있는가, 또는 미룰 수 있게 만들 수 있는가? (Step 02, 12) — 결정하지 않는 구조(포트, 모듈 경계)가 결정보다 나을 때가 많다.
- 무엇을 얻고, 무엇을 지불하는가? (Step 04) — 지불 항목이 안 보이면 결정할 준비가 안 된 것이다.
- 그 “얻는 것”은 측정 가능한 문장인가? (Step 04) — 품질 속성 시나리오로 쓸 수 없는 이득은 소망이지 근거가 아니다.
- 변경의 결을 따르는가? (Step 02, 05) — 함께 바뀌는 것이 같은 쪽에 묶이는가. 자주 바뀌는 것이 화살표를 받게 되지는 않는가(Step 03).
- 팀 경계와 정렬되는가? (Step 09) — 이 경계를 한 팀이 소유할 수 있는가. 아니라면 다이어그램은 조직에 진다.
- 데이터 소유권과 트랜잭션 경계는? (Step 07, 11) — 코드 경계가 아무리 고와도 공유 데이터가 그것을 무효화한다. 경계에 걸치는 원자성 요구가 있다면 경계가 틀렸다는 신호부터 의심하라. 그리고 그 경계가 프로세스를 넘는다면 — 분산의 물리학(부분 실패, CAP, 지연)을 지불할 준비가 됐는가(Step 10)?
- 방어선은 무엇인가, 그리고 기록했는가? (Step 12, 이 장) — 이 결정을 지킬 적합도 함수 한 줄, 그리고 ADR 한 장. 이 둘이 없으면 결정은 6개월짜리다.
5. 흔한 오해 바로잡기
오해 1: “선택 가이드가 있다면 결정 트리로 만들 수 있다.” 다이얼은 이산값이 아니라 연속값이고, 서로 독립도 아니다(도메인이 복잡해지면 팀이 커지고, 팀이 커지면 수명이 길어진다). 2절은 판단을 대체하는 순서도가 아니라 판단이 살펴야 할 변수 목록이다. 자동화할 수 있는 결정은 1번 질문에서 이미 걸러졌어야 한다 — 되돌리기 싼 결정이므로.
오해 2: “ADR은 관료제다.” 관료제는 결정을 늦추는 문서다. ADR은 이미 내린 결정을 박제하는 문서이고, 잘 쓰면 반 페이지다. 진짜 비교 대상은 “ADR 쓰는 15분”이 아니라 “2년 뒤 그 결정의 이유를 고고학하는 2주”다 — 그리고 그 고고학은 대개 실패한다.
오해 3: “결정했으면 끝이다.” ADR의 Status 필드와 supersede 메커니즘이 반대를 말한다. 결정은 그때의 Context 위에서만 옳고, Context는 변한다(Lehman). 좋은 팀은 결정을 번복하는 것을 실패가 아니라 학습의 기록으로 다룬다 — 단, 번복도 새 ADR로.
오해 4: “넷플릭스/아마존이 하는 방식이 우리의 목표다.” 그들의 답은 그들의 다이얼 값(수백 팀, 행성 규모 트래픽, 초장수명)에 대한 least worst다. 다이얼 값이 다른데 답을 복사하는 것은, 남의 처방전으로 약을 먹는 일이다 — 이 책이 아키텍처를 정답이 아니라 계기의 역사로 쓴 이유가 정확히 이것이다.
6. 요약
- 정답표는 없다. 세 다이얼(도메인 복잡도, 조직 규모, 수명·무결성)을 읽고, 안에서 밖으로(도메인 → 경계 → 배포) 결정하며, 배포는 가능한 한 미룬다.
- ADR(Nygard, 2011): Context(그때 알던 것) / Decision / Consequences(지불 항목 필수). 불변, 대체(supersede), 코드 옆에. 되돌리기 비싼 결정이면 쓴다.
- 체크리스트 여덟 질문: 되돌리기 비싼가 → 미룰 수 있는가 → 무엇을 지불하는가 → 측정 가능한가 → 변경의 결 → 팀 정렬 → 데이터 소유권 → 방어선과 기록.
- 첫 문장의 회귀: 아키텍처 = 되돌리기 비싼 결정 + 근거, 구조는 흔적, 지키는 활동까지가 아키텍처. 유행이 아니라 고통에서 출발하라.
다음 글: 닫는 글 · 다시, 변경 앞에서. 이 책의 첫 문장을 다시 꺼내, 열다섯 장의 도구를 실제 변경 앞에서 어떻게 쓰는지 한 번 더 묶는다.
원전
| 연도 | 문헌 | 이 장에서의 역할 |
|---|---|---|
| 2011 | Nygard, Documenting Architecture Decisions (블로그) | ADR의 원전 — Title/Status/Context/Decision/Consequences |
| 2020 | Ford & Richards, Fundamentals of Software Architecture | 제1법칙·least worst의 회수 (Step 04) |
| — | 이 책의 Step 01~14 | 체크리스트 여덟 질문의 출처 — 각 질문이 장 하나씩을 압축 |