diff --git "a/ch19_\354\225\204\355\202\244\355\205\215\354\262\230_\352\262\260\354\240\225/ch19_eden.md" "b/ch19_\354\225\204\355\202\244\355\205\215\354\262\230_\352\262\260\354\240\225/ch19_eden.md"
new file mode 100644
index 0000000..0b57333
--- /dev/null
+++ "b/ch19_\354\225\204\355\202\244\355\205\215\354\262\230_\352\262\260\354\240\225/ch19_eden.md"
@@ -0,0 +1,245 @@
+# 아키텍처 결정
+
+아키텍트의 핵심 역할은 **아키텍처 결정을 내리는 것**입니다.
+아키텍처 결정에는 시스템 구조뿐만 아니라, 아키텍처 특성에 영향을 미치는 다양한 기술 결정을 포함합니다.
+아키텍트는 정보를 수집하고, 결정을 정당화 및 문서화한 뒤, 이해관계자와 효과적으로 소통해야 합니다.
+
+## 19.1 아키텍처 결정 안티패턴
+
+아키텍처 결정에서 주로 발생하는 대표적인 안티패턴으로는 ‘**네 패를 먼저 보여주지마**’, ‘**무한반복 회의**’, **‘이메일 기반 아키텍처’**가 있으며, 이들은 서로 연계되어 누적되는 경향이 있습니다.
+
+### 19.1.1 ‘네 패를 먼저 보여주지마’ 안티패턴
+
+이 안티패턴은 잘못된 선택을 두려워해 결정을 회피하거나 미루는 현상을 말합니다.
+이를 극복하는 방법은 두 가지입니다.
+
+1. **중요한 결정을 내리기 전, 책임질 수 있는 마지막 순간까지 기다리기**: 충분한 정보를 수집해 결정을 검증하고 정당화하되, 지나치게 시간을 끌지 않아야 합니다.
+2. **개발팀과 지속적 협력**: 아키텍트가 결정한 내용을 의도한 대로 추진하며, 개발팀의 도움을 받아 문제 발생 시 신속히 대응할 수 있도록 합니다.
+
+예를 들어 개발 과정에서 일부 서비스의 확장성 요건으로 인해 메모리 사용량이 예상보다 많아지면, 아키텍트는 개발팀과 협력하여 아키텍처를 조정해야 합니다.
+
+### 19.1.2 ‘무한반복 회의’ 안티패턴
+
+이 안티패턴은 어떤 결정을 왜 했는지 알지 못한 채, 회의만 계속 반복하는 상황을 의미합니다.
+이는 아키텍트가 자신의 결정을 정당화하지 못할 때 발생하며, 방지를 위해서는 결정의 기술적, 비즈니스적 근거를 명확히 제시해야 합니다.
+예를 들어, 모놀리식 애플리케이션을 개별 서비스로 분리하는 아키텍처 리팩터링은 기술적으로 자원 사용과 관리 효율성을 높이는 동시에, 비즈니스적으로도 신기능 출시를 앞당기고 개발 비용을 절감할 수 있다는 점을 명확히 설명할 수 있어야 합니다.
+아키텍처 결정을 정당화하려면 비즈니스 가치를 제시하는 것이 중요합니다.
+일반적인 요소로는 비용, 출시 시기, 유저 만족도, 전략적 포지셔닝 등을 꼽을 수 있으며, 이들 중 이해관계자에게 무엇이 중요한지 고려해야 합니다.
+
+### 19.1.3 ‘이메일 기반 아키텍처’ 안티패턴
+
+이 안티패턴은 소통 수단으로 이메일을 사용하고, 결정 사항을 체계적으로 문서화하지 않은 탓에, 아키텍처 결정을 제대로 전달하지 못해 사람들이 결정을 놓쳐버리는 상황을 의미합니다.
+이를 방지하려면 단일 기록 시스템에 아키텍처 결정의 세부 정보를 보관해야 합니다.
+이를 통해 기록의 일관성을 유지하고, 결정의 변경 사항을 효과적으로 전달할 수 있습니다.
+또한 아키텍처 결정은 관련자에게만 통지하고, 이메일에는 결정의 맥락만 언급하며, 세부 정보는 링크로 제공해야 합니다.
+
+## 19.2 아키텍처적으로 중요한
+
+다소 기술적인 내용이더라도, 그것이 아키텍처 특성을 직접 지원하기 위해 선택된 기술이라면 이는 아키텍처 결정으로 간주할 수 있습니다.
+아키텍처 결정의 본질은 아키텍처적으로 중요한(architecturally significant) 것들이어야 한다는 것입니다.
+이는 **구조, 비기능적 특성, 의존성, 인터페이스, 구현 기술에 영향을 미치는 결정**이라고 정의할 수 있습니다.
+
+- **구조 (Structure)**
+ - 아키텍처의 패턴이나 스타일에 영향을 미치는 결정들.
+ - 예: 여러 마이크로서비스 간 데이터를 공유하기로 한 결정 -> 서비스 경계 콘텍스트와 애플리케이션 구조에 영향을 미침.
+- **비기능 특성 (Nonfunctional Characteristic)**
+ - 개발 및 유지보수 중인 시스템에서 중요한 아키텍처 특성.
+ - 예: 성능이 중요한 특성이고 기술 선택이 성능에 영향을 미칠 경우, 이는 아키텍처 결정이 됨.
+- **의존성 (Dependency)**
+ - 시스템 내부의 컴포넌트 또는 서비스 간 커플링 지점.
+ - 확장성, 모듈성, 민첩성, 시험성, 안정성 등에 영향을 미침.
+- **인터페이스 (Interface)**
+ - 서비스와 컴포넌트에 접근하고 조정하는 수단.
+ - 예: 계약 버저닝, 버전 구식화 등의 계약 정의 내용
+- **구현 기술 (Implementation Technique)**
+ - 플랫폼, 프레임워크, 도구, 프로세스와 관련된 결정.
+
+## 19.3 아키텍처 결정 레코드
+
+아키텍처 결정을 효과적으로 문서화하기 위해 **아키텍처 결정 레코드(ADR)** 가 사용됩니다.
+ADR은 보통 한두 페이지 분량의 짧은 텍스트 파일로, 아스키독(AsciiDoc), 마크다운(Markdown), 또는 위키 페이지 템플릿 포맷으로 작성됩니다.
+
+### 19.3.1 기본구조
+
+ADR(아키텍처 결정 레코드)의 기본 구조는 다음 5개 섹션으로 구성됩니다: **제목(Title), 상태(Status), 콘텍스트(Context), 결정(Decision), 결과(Consequences)**.
+여기에 **컴플라이언스(Compliance), 노트(Notes)** 섹션을 추가할 수 있습니다.
+필요에 따라 섹션을 확장하거나 대안 분석 결과를 기록하는 **대안(Alternatives)** 섹션을 추가할 수 있습니다.
+
+#### 제목
+
+ADR의 제목은 일련 번호와 함께 아키텍처 결정을 간결한 문구로 표현합니다.
+예를 들어, “42. 주문 서비스와 결제 서비스 간의 비동기 메시징 사용”과 같이 짧고 명료하게 작성합니다.
+
+#### 상태
+
+ADR의 **상태(Status)**는 다음 세 가지로 표시됩니다:
+
+1. **제안됨(Proposed)**: 상위 의사 결정권자의 승인이 필요한 상태.
+ - 제안됨 상태의 ADR은 수락됨 상태가 될 때까지 계속 수정됩니다.
+2. **수락됨(Accepted)**: 결정이 승인되어 구현 준비가 된 상태.
+3. **대체됨(Superseded)**: 이전에 수락된 결정이 번복되어 다른 ADR에 의해 대체된 상태.
+ - 제안됨 상태의 ADR은 대체되지 않습니다.
+
+대체됨 상태는 어떤 결정이 내려졌고, 당시 왜 그런 결정을 했는지, 새로운 결정은 무엇이고, 왜 변경을 하게 됐는지 등에 관한 이력을 관리합니다.
+어떤 ADR이 대체되면 그 ADR을 대체한 결정이 병기되며, 반대로 ADR을 대체한 결정에는 자신이 대체한 ADR이 병기됩니다.
+이와 같이 기록하면 과거 결정의 변경 사유와 새로운 결정의 배경을 명확히 알 수 있어, 불필요한 혼란을 방지할 수 있습니다.
+
+```
+ADR 42. 주문 서비스와 결제 서비스 간의 비동기 메시징 사용
+상태: 68로 대체됨
+
+ADR 68. 주문 서비스와 결제 서비스 간의 REST 사용
+상태: 수락됨, 42를 대체함
+```
+
+ADR의 상태 섹션에는 아키텍처 결정이 승인되기 위한 기준과 절차를 명확히 하여, 상사나 다른 유관자들과 승인 절차를 논의하도록 돕습니다.
+이를 위한 주요 주제는 비용, 전체 팀 영향도, 보안입니다.
+
+- **비용**:
+ - 소프트웨어 구매, 라이선스, 추가 하드웨어, 구현 공수 등이 포함됩니다.
+ - 공수의 경우 예상 소요 시간과 FTE(full-time equivalency)를 기준으로 계산하며, PO나 PM이 이를 파악하고 있습니다.
+ - 비용이 정해진 한도를 초과하면, ADR의 상태를 제안으로 설정하고 다른 승인자의 승인을 기다려야 합니다.
+- **전체 팀 영향도 및 보안**:
+ - 아키텍처 결정이 다른 팀, 시스템, 보안에 영향을 미칠 경우, 상위 협의체의 승인이 필요합니다.
+
+예를 들어 **“1천만 원 초과 비용은 아키텍처 검토 위원회 승인 필요”**와 같은 지출 한도를 설정하고 이를 문서화하면, ADR 승인 기준이 명확해져서 아키텍트 스스로 승인 가능한 결정과 그렇지 않은 결정을 구별할 수 있습니다.
+
+#### 콘텍스트
+
+ADR 콘텍스트 섹션은 결정의 배경이 되는 불가항력적인 요소를 설명하고, 다른 대안들에 대해서 논의하는 부분입니다.
+각 대안에 대한 상세한 분석이 필요한 경우, 대안 분석 섹션을 추가해 세부 내용을 기록합니다.
+
+콘텍스트 섹션을 통해 아키텍처를 간결하고 효과적으로 문서화할 수 있으며, 특정 아키텍처 영역을 명확히 기술해야 합니다.
+예를 들어 다음과 같이 시나리오와 대안을 포함해 아키텍처를 설명하는 간결한 문장으로 구성할 수 있습니다.
+
+```
+주문의 총 결제 금액을 주문 서비스가 처리하려면 결제 서비스에 정보를 전달해야 하며, 이는 REST 또는 비동기 메시징으로 수행할 수 있다.
+```
+
+#### 결정
+
+결정 섹션에는 아키텍처 결정과 그 이유를 명확히 기술합니다.
+결정에는 수동적 어조 대신 긍정적이고 단호한 어조로 작성해야 설득력이 높아지고, 의견 표현을 넘어 실제 결정으로 전달됩니다.
+
+- 비권장: “비동기 메시징이 최선의 선택이라고 생각합니다.”
+- 권장: “서비스 간에는 비동기 메시징을 사용할 것입니다.”
+
+**결정 섹션의 강점**은 **'어떻게(How)'보다 '왜(Why)'**에 중점을 두는 데 있습니다.
+작동 원리는 콘텍스트 다이어그램으로 추측할 수 있지만, 결정 이유는 그렇지 않습니다.
+**결정 이유**와 **배경**을 명확히 알면, 문제의 맥락을 이해하고, 실수를 예방하기 위해 리팩터링을 하는 것도 사능합니다.
+
+구글은 과거 두 서비스 간 통신 수단으로 gRPC를 선택했지만, 이유를 명확히 기록하지 않아 문제가 발생했습니다.
+시간이 지나 다른 아키텍트가 이 결정을 무시하고 메시징 방식으로 리팩터링을 진행했으나, 레이턴시 급증과 타임아웃 문제가 발생했습니다.
+gRPC 선택 이유가 레이턴시 최소화였음을 알았다면, 불필요한 리팩터링을 피할 수 있었을 것입니다.
+
+#### 결과
+
+결과(Consequences) 섹션은 **아키텍처 결정의 전체적인 영향도를 기술**하는 중요한 부분입니다.
+이 섹션에서 결정의 장점과 단점을 구체적으로 기술하여, 아키텍처 결정이 어떤 영향을 미치는지를 다시 검토할 수 있습니다.
+또한 비용이나 다른 아키텍처 특성과 관련된 트레이드오프 분석 결과를 문서화할 수도 있습니다.
+예를 들어, 비동기 메시징 방식을 사용해 리뷰 게시 요청의 응답 시간을 크게 개선(3,100ms → 25ms)했다고 합시다.
+비동기 요청은 복잡한 에러 처리 문제를 동반할 수 있지만, 응답성 향상과 비즈니스 가치를 고려한 결과임을 트레이드 오프 분석 결과로 명시할 수 있습니다.
+이와 같이 트레이드오프와 결정 과정을 문서화하여, 잠재적인 이슈를 예방하고 아키텍처 전반의 맥락을 명확히 할 수 있습니다.
+
+#### 컴플라이언스
+
+컴플라이언스 섹션은 표준은 아니지만 추가하기를 권장합니다.
+이 섹션에는 **아키텍처 결정을 컴플라이언스 관점에서 어떻게 측정하고 관리할지** 작성합니다.
+컴플라이언스 체크를 수동으로 할지 또는 피트니스 함수를 통해 자동화할지를 결정해야 하며, 자동화를 선택한다면 피트니스 함수 작성 방법과 코드베이스 변경이 필요한지를 기록해야 합니다.
+수행할 테스트, 테스트의 위치, 그리고 테스트 실행 시기 및 방법을 함께 정의합니다.
+
+예를 들어, 전통적인 n-티어 아키텍처에서 공유 기능은 공유 서비스 레이어에 분리하여 구현하기로 결정했다고 가정합니다.
+이 결정은 Java ArchUnit이나 .NET NetArchTest를 활용해 자동으로 측정 및 관리할 수 있습니다.
+아래와 같이 피트니스 함수를 정의하고, @SharedService 애너테이션을 모든 공유 클래스에 적용하여 컴플라이언스 체크를 자동화할 수 있습니다.
+
+```java
+@Test
+public void shared_services_should_reside_in_services_layer() {
+ classes()
+ .that()
+ .areAnnotatedWith(SharedService.class)
+ .should()
+ .resideInAPackage("..services..")
+ .because("비즈니스 레이어에서 비즈니스 객체가 사용하는 " +
+ "모든 공유 객체는 공유 서비스 레이어에 두고 " +
+ "공유 기능을 분리하여 구현한다.")
+ .check(myClasses);
+}
+```
+
+#### 노트
+
+다양한 메타데이터(원저자, 승인일, 승인자, 대체일, 최종 수정일, 수정자, 최종 수정 내역)로 구성된 노트 섹션을 추가하는 것이 권장됩니다.
+ADR을 버전 관리 시스템에 저장할 때, 해당 시스템에 저장되지 않는 부가적인 메타 정보를 이곳에서 보완할 수 있습니다.
+
+### 19.3.2 ADR 저장
+
+아키텍처 결정들은 개별 파일이나 위키 페이지 형태로 관리되어야 합니다.
+많은 아키텍트들이 ADR을 Git 리포지터리에 저장하지만, 대규모 조직에서는 다음과 같은 문제를 고려해야 합니다:
+
+1. 일부 사용자는 Git 리포지터리에 접근할 수 없습니다.
+2. 통합 아키텍처나 공통 결정과 같이, Git 리포지터리 외부의 콘텍스트를 포함한 ADR을 Git에 저장하는 것이 적절하지 않습니다.
+
+따라서, 위키 또는 문서 렌더링 소프트웨어와 같이 쉽게 접근할 수 있는 공유 파일 서버에 저장하는 것이 좋습니다.
+
+디렉터리 구조는 다음과 같이 구성할 수 있습니다.:
+
+1. application: 애플리케이션 콘텍스트의 아키텍처 결정을 포함하며, 다음의 서브디렉터리를 포함합니다.
+ - common: 모든 애플리케이션에 공통적으로 적용되는 결정 (예: 특정 애너테이션 사용 규칙).
+ - 특정 애플리케이션 디렉터리 (예: atp, pstd): 특정 애플리케이션에만 적용되는 아키텍처 결정
+2. integration: 애플리케이션, 시스템, 서비스 간 통신과 관련된 아키텍처 결정
+3. enterprise: 전사적으로 영향을 미치는 아키텍처 결정
+ - ex) 모든 데이터베이스 액세스는 데이터베이스를 소유한 시스템만 가능하다.
+
+
+
+ADR을 위키에 저장하면, 디렉터리 구조가 그대로 네비게이션 랜딩 페이지로 활용됩니다.
+각 디렉터리(application, integration, enterprise)는 하나의 랜딩 페이지가 되고, ADR은 개별 위키 페이지로 표시됩니다.
+
+### 19.3.3 ADR로 문서화
+
+ADR은 소프트웨어 아키텍처를 효과적으로 문서화하는 도구입니다.
+콘텍스트 섹션은 아키텍처 결정이 필요한 시스템의 영역과 결정의 대안을 기술하며, 결정 섹션은 결정 이유를 명확히 설명합니다.
+또한, 결과 섹션에서는 확장성과 성능 간 트레이드오프 같은 추가적인 배경을 기술합니다.
+이러한 정보들이 모여 아키텍처 문서화의 완성도를 높입니다.
+
+### 19.3.4 ADR로 표준화
+
+ADR 표준화는 일하는 방식을 통제하지 않는 선에서 표준을 제시할 수 있습니다.
+콘텍스트 섹션은 표준을 강제해야 하는 상황을 설명하고, 결정 섹션은 해당 표준을 우선시해야 하는 이유를 명확히 기술해 개발자가 이를 납득하고 따르게 합니다.
+또한, 결과 섹션은 표준의 타당성과 결과를 스스로 검증할 수 있게 하여, 필요시 표준을 재고하거나 변경할 수 있게 합니다.
+
+### 19.3.5 예시
+
+경매 시스템 구축 예제에서는, 해당 시스템에서 필요로 하는 다양한 아키텍처 결정이 언급됩니다.
+주요 결정에는 이벤트 기반 마이크로서비스 사용, 입찰자와 경매인 UI 분리, 실시간 전송 프로토콜(RTP) 활용, 단일 레이어 구조, 메시지 발행/구독 방식 채택 등이 포함됩니다.
+이와 같은 각 결정들의 이유은 명확히 문서화 되어야 합니다.
+
+다음은 BidCapture, Bidstreamer, BidTracker 서비스 간의 메시지 발행/구독 시스템에 대한 결정 사례입니다.
+
+
+
+```
+ADR 76. 입찰 서비스 간 펍/섭 메시징
+
+콘텍스트
+
+BidCapture 서비스는 온라인 입찰차 또는 경매인을 통한 라이브 입찰자로부터 입찰을 받아 BidStreamer 서비스, BidTracker 서비스에 전달해야 한다.
+입찰은 비동기 점대점(p2p), 비동기 pub/sub, 온라인 경매 API를 통한 REST 방식으로 전달할 수 있다.
+
+결정
+
+BidCapture, Bidstreamer, BidTracker 세 서비스는 비동기 펍/섭 메시지를 주고받기로 결정할 예정이다. BidStreamer 서비스는 BidCapture 서비스가 받은 순서 그대로 입찰을 수신해야 한다.
+메시징과 큐는 스트림의 입찰 순서를 자동으로 보장한다.
+비동기 펍/섭 메시징을 사용하면 입찰 프로세스의 성능이 개선되고 입찰 정보를 확장할 수 있다.
+
+결과
+
+메시징 큐의 고가용성이 필요하고 클러스터 구성을 해야 할 것이다.
+내부 입찰 이벤트는 API 레이어에서 수행되는 보안 체크를 우회할 것이다.
+업데이트: 2020년 4월 14일 ARB 회의에서 검토한 결과, ARB는 위와 같은 트레이드오프를 수용하기로 판단했으며, 세 서비스 간 입찰 이벤트에 추가적으로 보안 체크는 필요하지 않다고 결론지었다.
+
+컴플라이언스
+
+주기적으로 수동 코드 검사 및 설계 리뷰를 실시하여 BidCapture, BidStreamer, BidTracker 세 서비스 간에 비동기 펍/섭 메시징이 제대로 이뤄지고 있는지 확인할 예정이다.
+```
diff --git "a/ch19_\354\225\204\355\202\244\355\205\215\354\262\230_\352\262\260\354\240\225/ch19_eden/19-3.png" "b/ch19_\354\225\204\355\202\244\355\205\215\354\262\230_\352\262\260\354\240\225/ch19_eden/19-3.png"
new file mode 100644
index 0000000..dcb5a9d
Binary files /dev/null and "b/ch19_\354\225\204\355\202\244\355\205\215\354\262\230_\352\262\260\354\240\225/ch19_eden/19-3.png" differ
diff --git "a/ch19_\354\225\204\355\202\244\355\205\215\354\262\230_\352\262\260\354\240\225/ch19_eden/19-4.png" "b/ch19_\354\225\204\355\202\244\355\205\215\354\262\230_\352\262\260\354\240\225/ch19_eden/19-4.png"
new file mode 100644
index 0000000..c68b029
Binary files /dev/null and "b/ch19_\354\225\204\355\202\244\355\205\215\354\262\230_\352\262\260\354\240\225/ch19_eden/19-4.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden.md" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden.md"
new file mode 100644
index 0000000..5e3e1e1
--- /dev/null
+++ "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden.md"
@@ -0,0 +1,271 @@
+# 아키텍처 리스크 분석
+
+아키텍처는 항상 리스크를 내포하며, 리스크 분석을 통해 내부 결함을 파악하고 리스크를 줄이는 작업이 필요합니다.
+본 장에서는 리스크 스토밍(Risk Storming)을 활용하여 리스크를 도출, 평가, 식별하는 방법과 프랙티스를 다룹니다.
+
+## 20.1 리스크 매트릭스
+
+아키텍처 리스크 평가 시, 리스크를 낮음/중간/높음으로 분류해야 하는데, 이 과정은 주관적일 수 있습니다.
+이 때 리스크 매트릭스를 활용하면, 주관성을 줄이고 특정 아키텍처 영역에서 리스크를 효과적으로 찾아낼 수 있습니다.
+
+아키텍처 리스크 매트릭스는 **리스크 영향도**와 **발생 가능성**의 두 차원을 기반으로 리스크를 평가하며, 낮음(1), 중간(2), 높음(3) 등급으로 분류됩니다.
+**각 등급의 숫자를 곱해 리스크를 정량화**하며, 1-2는 낮은 리스크(밝은 회색), 3-4는 중간 리스크(중간 회색), 6-9는 높은 리스크(짙은 회색)로 표시됩니다.
+
+
+
+## 20.2 리스크 평가
+
+리스크 평가는 전체 아키텍처의 리스크를 리스크 매트릭스를 기반으로 유의미한 평가 기준에 따라 정리한 리포트입니다.
+리스크 평가는 애플리케이션의 서비스나 도메인 영역에 기반한 평가 기준을 포함합니다.
+
+
+
+리스크 매트릭스를 활용하면 평가 기준별로, 서비스 또는 도메인 영역별로 누적 리스크를 계산할 수 있습니다.
+위 예제에서는 데이터 무결성의 누적 리스크는 17점으로 가장 높고, 가용성은 10점으로 가장 낮습니다.
+도메인 영역에서는 고객 등록이 24점으로 가장 높은 리스크를 가지며, 주문 이행은 8점으로 가장 낮습니다.
+이와 같이 각 영역별 수치를 상대적으로 비교하여, 특정 리스크 범주나 도메인 영역에서의 리스크가 개선 또는 악화 되었는지를 알 수 있습니다.
+
+위 예제에서는 모든 리스크 분석 결과를 담았지만, 효과적인 메시지 전달을 위해서는 일부 결과로 필터링하는게 좋습니다.
+예를 들어, 리스크가 높은 시스템 영역만 발표하면 다음처럼 SNR(신호대잡음비, signal-to-noise-ratio)이 개선되어 시스템 상태가 명확하게 드러납니다.
+
+
+
+지금까지 살펴본 리스크 평가는 특정 시점의 리스크 상태를 보여주는 스냅샷의 일종으로, 리스크의 방향성을 알려주지는 않습니다.
+리스크 방향성을 표시할 때는 플러스(+), 마이너스(-) 기호를 사용하면 좋습니다.
+예를 들어, 다음 예제에서는 고객 등록의 성능은 리스크 등급이 중간(4)이나, 마이너스 부호로 점점 상황이 악화되고 있음을 나타냅니다.
+반면, 카탈로그 체크아웃의 확장성은 등급이 높고(6) 플러스 부호로 개선 중임을 보여줍니다.
+부호가 없으면 리스크가 안정적이고, 개선 또는 악화되지 않았다는 뜻입니다.
+
+
+
+다만 플러스/마이너스 부호가 헷갈리는 경우를 대비해, 리스크 등급 번호와 화살표를 함께 표기할 수도 있습니다.
+다음과 같이 화살표로 방향을 명확히 표시하면 따로 범례가 필요 없으며, 화살표에 색깔(빨간색: 악화, 초록색: 개선)을 추가하면 리스크의 방향성을 더욱 직관적으로 전달할 수 있습니다.
+
+
+
+## 20.3 리스크 스토밍
+
+리스크 스토밍은 여러 관계자가 모여 특정 범위 내 아키텍처 리스크를 찾아내는 협력적인 활동입니다.
+일반적인 리스크 영역에는 **검증되지 않은 기술, 성능, 확장성, 가용성, 데이터 소실, 단일 장애 지점, 보안** 등이 포함됩니다.
+이 활동에는 아키텍트뿐 아니라 개발자, 기술 책임자가 함께 참여하면, 구현 관점에서도 리스크를 검토할 수 있습니다.
+
+리스크 스토밍은 개별 파트와 협력 파트로 이루어지며, 두 활동이 함께 진행되어야 효과적인 리스크 스토밍이 가능합니다.
+
+- **개별 파트**:
+ - 참가자들이 독립적으로 리스크 매트릭스를 활용해 각자 아키텍처 영역에 리스크를 할당합니다.
+ - 다른 사람의 영향 없이 집중할 수 있습니다.
+- **협력 파트**:
+ - 모든 참가자가 모여 리스크 영역에 대한 공감을 형성하고, 리스크를 줄이기 위한 방안을 논의합니다.
+
+리스크 스토밍에서는 아키텍처 다이어그램을 사용합니다.
+전체 리스크 평가에는 종합적인 아키텍처 다이어그램을 활용하고, 특정 영역에 대한 평가에는 해당 영역의 아키텍처 다이어그램을 활용합니다.
+리스크 스토밍을 주관하는 아키텍트는 다이어그램을 최신 상태로 유지하며, 모든 참가자들이 이를 확인할 수 있도록 관리해야 합니다.
+
+다음의 다이어그램은 AWS ELB가 웹 서버(Nginx)와 연결되고, 최종적으로 각 EC2 인스턴스에서 실행되는 애플리케이션 서비스에 요청을 전달합니다.
+애플리케이션 서비스는 MySQL, 레디스 캐시, 몽고DB를 호출하여 로깅 작업을 수행하며, 푸시 확장 서버도 호출됩니다.
+푸시 확장 서버는 다시 MySQL, 레디스 캐시, 몽고DB의 로깅 기능과 연계됩니다.
+
+
+
+리스크 스토밍은 다음의 세 가지 활동으로 구성됩니다.
+식별은 개별적으로, 합의와 완화는 협력적으로 진행됩니다.
+
+1. 식별(Identification): 개별적이고 비협력적으로 진행되며, 각자가 리스크를 파악합니다.
+2. 합의(Consensus): 모든 참가자가 모여 협력적으로 리스크에 대한 공감대를 형성합니다.
+3. 완화(Mitigation): 협력적으로 리스크를 줄이기 위한 방안을 논의하고 실행합니다.
+
+### 20.3.1 식별
+
+식별 활동은 참여자가 개별적으로 아키텍처 내 리스크 영역을 파악하는 과정으로, 다음 단계를 거칩니다:
+
+1. **초대장 발송**: 리스크 스토밍을 주관하는 아키텍트가 참가자들에게 초대장을 보내며, 초대장에는 아키텍처 다이어그램, 분석 대상 리스크 영역, 협력 파트 일정 및 장소가 포함됩니다.
+2. **리스크 분석**: 참가자는 리스크 매트릭스를 활용해 아키텍처를 분석하고, 리스크를 낮음(1-2), 중간(3-4), 높음(6-9)으로 분류합니다.
+3. **포스트잇 작성**: 리스크 매트릭스에서 식별한 리스크 번호를 색상별 포스트잇(초록: 낮음, 노랑: 중간, 빨강: 높음)에 기재합니다.
+
+리스크 스토밍은 보통 한 가지 부문(예: 성능)만 분석하지만, 필요에 따라 여러 부문(예: 성능, 확장성, 데이터 소실)을 동시에 분석할 수도 있습니다.
+예를 들어, 세 참가자가 중앙 데이터베이스에서 리스크 높음(6)을 식별했더라도, 한 명은 가용성 리스크, 나머지 두 명은 성능 리스크를 발견할 수 있습니다.
+이 경우, 참가자들은 포스트잇에 리스크 번호와 함께 부문명을 병기하여 구분하고, 각 부문을 별도로 논의해야 합니다.
+
+### 20.3.2 합의
+
+합의 활동은 참가자들이 아키텍처 내 리스크에 대해 공감대를 형성하는 협력적인 과정입니다.
+아키텍처 다이어그램을 대형 스크린에 표시한 상태에서, 참가자들은 각자가 발견한 리스크를 다이어그램에 배치합니다.
+이를 통해 리스크 영역에 대한 시각적 합의가 이루어집니다.
+
+
+
+리스크 배치가 끝나면 협력 파트가 시작됩니다.
+이 과정의 목표는 참가자들이 한 팀이 되어 리스크 영역을 분석하고, 해당 영역이 실제 리스크인지 합의하는 것입니다.
+위 예제에서는 다양한 아키텍처 리스크 영역이 식별되었습니다.
+
+1. 일래스틱 로드 밸런서:
+ - 리스크 중간(3): 2명
+ - 리스크 높음(6): 1명
+2. 푸시 확장 서버:
+ - 리스크 높음(9): 1명
+3. MySQL 데이터베이스:
+ - 리스크 중간(3): 3명
+4. 레디스 캐시:
+ - 리스크 높음(9): 1명
+5. 몽고DB 로깅:
+ - 리스크 낮음(2): 3명
+6. 기타 아키텍처 영역:
+ - 리스크 없음
+
+3번(MySQL 데이터베이스)과 5번(몽고DB 로깅)은 세 참가자가 모두 리스크 레벨과 당위성에 동의했으므로 추가 논의가 필요 없습니다.
+반면, 1번(일래스틱 로드 밸런서)은 의견 차이가 있어 논의가 필요하며, 2번(푸시 확장 서버)과 4번(레디스 캐시)은 한 명만 리스크로 식별했으므로 합의를 통해 검토해야 합니다.
+
+1번 일래스틱 로드 밸런서의 리스크에 대해, 두 참가자는 리스크 중간(3)으로, 한 참가자는 리스크 높음(6)으로 식별했습니다.
+리스크 높음으로 평가한 참가자는 **장애 발생 시 전체 시스템에 영향을 미친다**고 설명했으며, 이는 사실로 인정되었습니다.
+그러나 다른 두 참가자는 **그런 상황이 거의 발생하지 않을 것**이라 주장했고, **논의 끝에 세 번째 참가자는 리스크 레벨을 중간(3)으로 낮추기로 동의**했습니다.
+
+2번 푸시 확장 서버에 대해, 한 참가자는 리스크 높음(9)으로 식별했으나, 다른 두 참가자는 리스크가 없다고 보았습니다.
+리스크를 식별한 참가자는 **과거 부하가 큰 상황에서 푸시 확장 서버가 지속적으로 다운되는 문제를 목격한 경험**을 공유했습니다.
+이러한 논의를 통해 다른 참가자들도 미처 알지 못했던 리스크를 파악하게 되었으며, 이는 리스크 스토밍의 핵심 가치인 **협력과 정보 공유**의 중요성을 보여줍니다.
+
+4번 레디스 캐시에 대해서 한 참가자는 리스크 높음(9)으로 식별했지만, 다른 두 참가자는 리스크가 없다고 판단했습니다.
+이유를 묻자, **해당 참가자는 레디스 캐시가 무엇인지 모른다**고 답했습니다.
+리스크 스토밍에서 검증되지 않았거나 알려지지 않은 기술은 가장 높은 리스크 등급(9)을 매기게 됩니다.
+개발자가 리스크 스토밍에 참여하면 아키텍처에 대한 이해를 높이고, 아키텍트는 팀원의 기술적 공백이 리스크 요인임을 인지할 수 있습니다.
+
+합의 활동은 모든 참가자가 식별된 리스크 영역에 의견을 함께 할 때까지 반복됩니다.
+다음과 같이 최종 결과가 도출되면 다음 활동으로 넘어갑니다.
+
+
+
+### 20.3.3 완화
+
+참가자들은 합의 과정에서 식별된 리스크를 줄이거나 제거하는 방법을 모색하며, 필요에 따라 아키텍처의 일부 영역을 개선하거나 변경합니다.
+필요에 따라 아키텍처 전반을 변경해야 할 수도 있지만, 간단한 리팩터링(예: 배압 큐 추가)으로 해결 가능할 수도 있습니다.
+이 때 아키텍처 변경이 비용 대비 가치가 있는지 판단하게 되고, 필요하다면 비즈니스 이해관계자들을 설득해야 합니다.
+예를 들어, 리스크 스토밍을 통해 가용성 측면에서 중앙 데이터베이스의 리스크가 중간(4)으로 식별됐다고 합시다.
+중앙 데이터베이스의 리스크를 줄이기 위해 클러스터링 및 물리적 분리를 제안했으나, $20,000의 비용이 부담되어 거절될 수 있습니다.
+이에 대해 클러스터링은 포기하고 데이터베이스를 두 파트로 분리만 하는 방안으로 합의하여, $8,000의 비용으로 리스크를 완화하게 됩니다.
+리스크 스토밍 기법을 사용해서 리스크를 잘 정리해두면 이해관계자 간 협상에 효과적으로 사용할 수 있습니다.
+
+## 20.4 애자일 스토리 리스크 분석
+
+리스크 스토밍은 아키텍처뿐만 아니라 소프트웨어 개발 전반에도 활용 가능합니다.
+예를 들어, 애자일 이터레이션에서 유저 스토리를 완료하는데 존재하는 리스크를 평가할 수 있습니다.
+리스크 매트릭스를 활용해 이터레이션에서 스토리가 완료되지 않았을 때의 영향도와 스토리가 완료되지 않을 가능성을 분석하고, 리스크가 높은 스토리를 우선 추적 및 처리할 수 있습니다.
+
+## 20.5 리스크 스토밍 예시
+
+환자들의 건강 상태에 대해 간호사가 조언을 해주는 콜 센터 시스템의 요구사항이 다음과 같다고 합시다.
+
+1. **진단 엔진 사용**
+ - 질문을 받으면 간호사나 환자에게 의료 문제를 안내하는 서드파티 진단 엔진을 사용한다.
+2. **서비스 방식**
+ - 환자는 콜 센터에 전화를 걸어 간호사와 통화하거나, 셀프 서비스 웹사이트를 통해 진단 엔진에 직접 액세스할 수 있다.
+3. **동시 지원 규모**
+ - 전국적으로 250명의 간호사와 수십만 명의 셀프 서비스 환자를 동시에 지원해야 한다.
+4. **의무 기록 열람**
+ - 간호사는 환자의 의무 기록을 열람할 수 있지만, 환자는 자신의 의무 기록을 볼 수 없다.
+5. **법률 준수**
+ - **미국 의료 정보 이동 및 책임법**(HIPAA)에 따라, 의무 기록은 간호사 외의 누구도 의무 기록을 열람할 수 없어야 한다.
+6. **데이터 요청 처리**
+ - 전염병과 독감 유행 시즌에 데이터 요청이 급증해도, 시스템이 이를 감당할 수 있어야 한다.
+7. **간호사 연결**
+ - 간호사 프로필(예: 외국어 가능)에 따라 통화가 연결되어야 한다.
+8. **진단 엔진 성능**
+ - 서드파티 진단 엔진은 초당 약 500개의 요청을 처리할 수 있어야 한다.
+
+해당 서비스에 대해서 다음과 같이 아키텍처를 구성할 수 있습니다.
+
+
+
+먼저 아키텍처에는 총 3개의 웹 기반 유저 인터페이스가 존재합니다.
+
+- 셀프 서비스 인터페이스: 환자용.
+- 간호사 인터페이스: 전화를 받는 간호사용.
+- 관리 인터페이스: 간호사 프로필과 시스템 설정값을 관리.
+
+콜 센터는 크게 두 부분으로 구성됩니다.
+
+- 통화 접수기: 걸려온 전화를 받음.
+- 통화 라우터: 중앙 데이터베이스에서 간호사 프로필을 조회 후, 적절한 간호사에게 통화 연결.
+
+진단 시스템 API 게이트웨이는 이 아키텍처의 핵심으로, 요청을 보안 체크한 후 적절한 백엔드 서비스로 전달합니다.
+전체 시스템은 **사례 관리, 간호사 프로필 관리, 의무 기록 인터페이스, 외부 진단 엔진** 4개 주요 서비스로 구성되며, 외부 시스템 및 콜센터 연결용 전용 프로토콜을 제외한 모든 통신은 REST를 사용합니다.
+
+아키텍트는 리스크 평가를 위해 요구사항과 다이어그램을 재검토하여, 가용성, 탄력성, 보안 측면에서 리스크 수준을 파악하려 합니다.
+리스크를 확인한 후 이를 줄이기 위한 아키텍처 개선 방안을 고민할 계획입니다.
+
+### 20.5.1 가용성
+
+아키텍트는 1차 리스크 스토밍 세션에서 시스템 성공을 위해 가용성을 최우선으로 검토했습니다.
+참가자들은 협력을 통해 리스크 매트릭스를 작성하고, 가용성과 관련된 주요 리스크 영역을 도출했습니다.
+
+- 중앙 데이터베이스:
+ - 영향도: 높음 (3)
+ - 가능성: 중간 (2)
+ - 리스크 수준: 높음 (6)
+- 진단 엔진 7 요소:
+ - 영향도: 높음 (3)
+ - 가능성: 알 수 없음 (2)
+ - 리스크 수준: 높음 (9)
+- 의무 기록 가용성:
+ - 시스템 실행에 필수 컴포넌트가 아님
+ - 리스크 수준: 낮음 (2)
+- 기타 시스템 파트
+ - 각 서비스 : 여러 인스턴스로 구성
+ - API 게이트웨이: 클러스터링 처리
+ - 가용성 측면에서 리스크 없음
+
+
+
+참가자들은 데이터베이스가 다운되면 간호사는 수기로 사례 기록을 작성할 수 있지만, 통화 라우터는 작동하지 않을 것이라는 점에 동의했습니다.
+이를 완화하기 위해 **데이터베이스를 두 개로 분리**하기로 했습니다: 간호사 프로필 정보용 클러스터형 데이터베이스, 사례 기록용 단일 인스턴스 데이터베이스.
+이 변경으로 **데이터베이스 가용성 우려가 해소되고, 사례 기록은 관리자만 볼 수 있어 보안도 강화**되었습니다.
+통화 라우터에 캐시를 도입하는 방법도 고려했으나, 통화 라우터의 구현 코드가 서드파티 제품일 가능성이 높으므로, 데이터베이스 액세스 방식을 채택했습니다.
+
+외부 시스템(진단 엔진, 의무 기록 시스템)은 제어가 어려워 가용성 관리에 리스크가 큽니다.
+이를 완화하기 위해 각 시스템의 SLA(서비스 수준 계약)나 SLO(서비스 수준 목표)를 확인하는 것이 권장됩니다.
+진단 엔진은 SLA로 99.99% 가용성(연간 다운타임 52.60분)을, 의무 기록 시스템은 99.9% 가용성(연간 다운타임 8.77시간)을 보장하며, 이는 상대적으로 리스크가 낮은 수준으로 평가됩니다.
+
+이후 변경된 아키텍처 다이어그램에서는 데이터베이스를 두 개로 분리하고, SLA를 다이어그램에 명시해 리스크를 줄였습니다.
+
+
+
+### 20.5.2 탄력성
+
+2차 리스크 스토밍에서는 탄력성, 특히 **사용자 부하 급증에 따른 가변 확장성**을 논의했습니다.
+독감 시즌에 **셀프 서비스 파트를 통해 진단 엔진에 많은 액세스가 몰려서, 진단 인터페이스의 부하가 크게 증가**할 가능성이 제기되었습니다.
+참가자들은 **진단 엔진 인터페이스를 리스크 높음(9)으로 만장일치로 식별**했습니다.
+초당 500개 요청 처리 능력으로는 예상되는 부하를 감당하기 어렵다고 판단했으며, REST 프로토콜을 사용하는 경우 문제가 더욱 심각해질 것으로 보았습니다.
+
+참가자들은 다음과 같은 방안을 검토했습니다.
+
+- **API 게이트웨이와 진단 엔진 인터페이스 사이에 비동기 큐 배치**: 둘 사이의 호출을 완충하는 것이 가능하지만, 대기 시간 증가와 타임아웃 가능성이 있습니다.
+- **앰뷸런스 패턴을 적용하여, 셀프 서비스보다 간호사 요청에 더 높은 우선순위를 부여**: 메시지 채널 2개를 필요로 하고, 대기 시간 문제는 여전히 해결되지 않습니다.
+- **발병 관련 진단 질문을 캐시**: 진단 엔진 인터페이스에 도달하는 호출을 줄일 수 있어서, 리스크를 효과적으로 완화할 수 있습니다.
+
+논의 결과, 새로운 아키텍처에서는 **간호사용과 셀프 서비스 환자용으로 나뉜 2개의 큐 채널**이 도입되고, **특정 질병 및 독감 관련 요청을 처리하는 질병 진단 캐시 서버**가 새로 도입되었습니다.
+이 구조는 진단 엔진 호출의 병목을 제거하여, 수만 개의 요청을 동시에 처리할 수 있습니다.
+
+
+
+### 20.5.3 보안
+
+아키텍트는 시스템의 또 다른 중요한 특성인 보안을 논의하기 위해 최종 세션을 열기로 했습니다.
+특히, HIPAA 규제 요구사항에 따라 **의무 기록은 간호사만 열람 가능하도록 안전하게 관리**해야 합니다.
+이 요구사항은 API 게이트웨이의 인증 및 인가 문제로 한정되지 않을 수 있습니다.
+
+진단 시스템 API 게이트웨이의 보안에 대한 리스크 스토밍 결과, 관리 직원이나 셀프 서비스 환자가 의무 기록을 열람할 리스크가 다음과 같이 평가되었습니다.
+
+- 진단 시스템 API 게이트웨이:
+ - 가능성: 중간(2)
+ - 영향도: 높음(3)
+ - 리스크 수준: 높음(6)
+
+각 API 호출에 대해 보안 체크가 이루어지긴 하지만, 모든 요청이 동일한 API 게이트웨이를 통과하기 때문에 가능성이 중간으로 판단되었습니다.
+참가자들은 API 게이트웨이를 사용자 유형 별로 관리자, 셀프 서비스/진단, 간호사용으로 분리하면, 관리자 또는 셀프 서비스 웹 인터페이스의 호출이 의무 기록 시스템에 접근하는 것을 막을 수 있다고 의견을 모았습니다.
+아키텍트는 이를 반영한 최종 아키텍처를 완성했습니다.
+
+
+
+리스크 스토밍을 통해 가용성, 탄력성, 보안 문제를 해결하는 데 있어 의미 있는 진전이 이루어졌습니다.
+잘 보이지 않는 리스크 영역을 다른 아키텍트, 개발자, 주요 이해관계자들과 협력하여 효과적으로 식별할 수 있었습니다.
+
+리스크 스토밍은 시스템이 운영되는 동안 지속적으로 반복해야 합니다.
+리스크 스토밍의 빈도는 변경 주기, 아키텍처 리팩터링, 점진적 개발 등 다양한 요인에 따라 달라지며, 일반적으로 주요 기능 추가 후, 또는 매 이터레이션 종료 시수행할 수 있습니다.
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-1.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-1.png"
new file mode 100644
index 0000000..9002be1
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-1.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-10.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-10.png"
new file mode 100644
index 0000000..5571013
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-10.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-11.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-11.png"
new file mode 100644
index 0000000..f85accf
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-11.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-12.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-12.png"
new file mode 100644
index 0000000..b624058
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-12.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-13.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-13.png"
new file mode 100644
index 0000000..a71e652
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-13.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-2.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-2.png"
new file mode 100644
index 0000000..fb7d264
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-2.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-3.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-3.png"
new file mode 100644
index 0000000..1858c15
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-3.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-4.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-4.png"
new file mode 100644
index 0000000..0d1d94f
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-4.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-5.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-5.png"
new file mode 100644
index 0000000..b1cd129
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-5.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-6.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-6.png"
new file mode 100644
index 0000000..d68104c
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-6.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-7.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-7.png"
new file mode 100644
index 0000000..2738e4b
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-7.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-8.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-8.png"
new file mode 100644
index 0000000..e3fbdc9
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-8.png" differ
diff --git "a/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-9.png" "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-9.png"
new file mode 100644
index 0000000..736a455
Binary files /dev/null and "b/ch20_\354\225\204\355\202\244\355\205\215\354\262\230_\353\246\254\354\212\244\355\201\254_\353\266\204\354\204\235/ch20_eden/20-9.png" differ
diff --git "a/ch21_\354\225\204\355\202\244\355\205\215\354\262\230_\353\217\204\354\213\235\355\231\224_\353\260\217_\355\224\204\353\240\210\354\240\240\355\205\214\354\235\264\354\205\230/ch21_eden.md" "b/ch21_\354\225\204\355\202\244\355\205\215\354\262\230_\353\217\204\354\213\235\355\231\224_\353\260\217_\355\224\204\353\240\210\354\240\240\355\205\214\354\235\264\354\205\230/ch21_eden.md"
new file mode 100644
index 0000000..3c51935
--- /dev/null
+++ "b/ch21_\354\225\204\355\202\244\355\205\215\354\262\230_\353\217\204\354\213\235\355\231\224_\353\260\217_\355\224\204\353\240\210\354\240\240\355\205\214\354\235\264\354\205\230/ch21_eden.md"
@@ -0,0 +1,139 @@
+# 아키텍처 도식화 및 프레젠테이션
+
+아키텍트로서 성공하려면 효과적인 의사 소통이 중요하며, 아키텍처 도식화와 프레젠테이션은 이를 위한 핵심 소프트 스킬입니다.
+이 두 스킬은 서로 다른 매체를 사용하지만, 아키텍처 비전의 중요한 부분을 시각적으로 표현한다는 공통점을 가집니다.
+
+아키텍처를 시각적으로 기술할 때는 **전체 아키텍처의 관점에서 시작하여, 개별 파트를 상세히 설명**해야 합니다.
+각 파트가 전체 아키텍처에서 어떤 위치에 있는지 명확히 알려주지 않으면 청중이 혼란스러울 수 있습니다.
+**표현 일관성**이란 다이어그램이나 프레젠테이션에서 **특정 파트에 대한 뷰를 보여주기 전에, 전체 아키텍처에서 파트 간의 관계를 설명**하는 것을 의미합니다.
+표현 일관성을 잘 지키면, 청중이 현재 표시된 내용의 범위를 쉽게 이해하고 혼동하지 않을 수 있습니다.
+예를 들어, 실리콘 샌드위치 카타에서 플러그인의 상호 연관성을 자세히 설명하려고 할 때, **전체 토폴로지를 표시한 뒤, 플러그인 구조를 하나씩 살펴보면서 이들 간의 관계를 설명**할 수 있습니다.
+
+
+
+## 21.1 도식화
+
+아키텍처 토폴로지를 통해 아키텍트와 개발자 간 공통 이해를 형성할 수 있기 때문에, 다이어그램을 작성하는 것은 아키텍트의 중요한 기술입니다.
+
+### 21.1.1 도구
+
+아키텍트는 강력한 다이어그램 도구를 선택하여 학습하는 것이 중요합니다.
+다만 설계 초기에는 정확도가 낮은 아티팩트부터 시작하는 것이 좋습니다.
+초반부터 다이어그램 작성에 많은 시간을 투자할수록, 그 결과물에 집착하게 됩니다.
+가능한 절차를 간소화하고. 적시에 아티팩트를 제작하는 것이 더 중요합니다.
+
+일반적으로는 화이트보드 보다 **태블릿과 프로젝터**가 더 선호됩니다.
+태블릿은 제한 없는 캔버스를 제공하여, 팀 작업에 필요한 그림을 자유롭게 추가할 수 있습니다.
+또한 다양한 시나리오를 복사 붙여넣기 하면서 실험할 수 있으며, 결과물을 깔끔하게 캡처할 수 있습니다.
+
+다이어그램 도구는 다양한 플랫폼에서 제공되며, 다음과 같은 필수 기능을 갖추고 있는지 확인하는 것이 중요합니다.
+
+- **레이어**:
+ - 항목을 논리적으로 나누고, 숨김/표시를 조정하여 세부 정보를 간단히 관리할 수 있습니다.
+ - 프레젠테이션 준비 시, 단계별로 그림을 그려서 시각적 자료로 사용 할 수 있습니다.
+- **스텐실/템플릿**:
+ - 스텐실(stencil)은 자주 사용되는 시각적 컴포넌트를 조합하여 라이브러리화할 수 있는 도구입니다.
+ - 공통적인 패턴이나 아티팩트를 스텐실로 구축하면, 조직 내 아키텍처 다이어그램을 일관되게 작성하고 빠르게 생성할 수 있습니다.
+- **마그넷**
+ - 마그넷은 도형 간 선을 쉽게 연결하도록 돕는 기능으로, 자동 정렬과 시각적 효과를 지원합니다.
+ - 일부 도구는 마그넷 추가 및 커스터마이징을 통해, 더욱 유연하게 도형을 연결할 수 있습니다.
+
+다이어그램 도구는 이러한 보조 기능 외에도, 선, 색상, 그 밖의 시각적인 아티팩트를 지원해야 하며, 다양한 포맷으로 내보내기도 가능해야 합니다.
+
+### 21.1.2 도식화 표준: UML, C4, ArchiMate
+
+#### UML
+
+통합 모델링 언어(UML)는 한때 널리 사용되었으나, 현재는 UML 클래스와 시퀀스 다이어그램을 제외한 다른 UML 다이어그램은 거의 쓰이지 않습니다.
+
+#### C4
+
+C4는 UML을 현대적인 방식으로 개선한 다이어그램 기법입니다.
+C4에서 ‘C’ 4개는 다음을 의미합니다.
+
+- **Context**: 유저 역할, 외부 의존성 등 시스템의 전체 컨텍스트
+- **Container**: 아키텍처 내부의 물리적 배포 경계로, 운영자와 아키텍트의 공통 관심사
+- **Component**: 시스템의 컴포넌트 뷰.
+- **Class**: UML과 동일한 스타일의 클래스 다이어그램을 사용
+
+C4 모델은 전사적 수준에서 도식화 표준으로 적합하지만, 모든 설계 요구를 충족하기에는 한계가 있습니다.
+모놀리식 아키텍처에는 적합할 수 있지만, 마이크로서비스 같은 분산 아키텍처에는 적합하지 않습니다.
+
+#### 아키메이트
+
+**비즈니스 도메인 중심으로 아키텍처를 기술, 분석, 시각화**하는 오픈 소스 엔터프라이즈 아키텍처 모델링 언어입니다.
+경량 모델링 언어를 제공하며, 단순함을 강점으로 가집니다.
+
+### 21.1.3 도식화 지침
+
+다음은 기술 다이어그램 작성 시 참고할 수 있는 일반적인 가이드라인 입니다.
+
+- **제목**
+ - 청중이 쉽게 이해할 수 있도록 **다이어그램의 모든 요소에 제목**을 붙입니다.
+ - **제목은 관련 항목에 고정**하고, 회전이나 이펙트를 활용하여 공간을 효율적으로 사용합니다.
+- **선**
+ - 선은 적절히 굵게 하여 가독성을 높입니다.
+ - **정보의 흐름을 나타낼 때는 화살표**로 트래픽 방향을 표시합니다.
+ - **화살표 머리의 모양은 종류별로 의미가 다를 수 있으므로 일관성 있게 사용**해야 합니다.
+ - **동기 통신은 실선, 비동기 통신은 점선**으로 나타냅니다.
+- **셰이프**
+ - 소프트웨어 업계 전체에서 통용되는 표준 셰이프는 없기 때문에, 아키텍트는 자신의 표준 셰이프 세트를 만들어 필요시 조직 전체에 전파하여 사용하도록 합니다.
+ - 일반적으로 배포 가능한 아티팩트는 3차원 상자로, 컨테이너는 직사각형으로 표현합니다.
+- **레이블**
+ - 다이어그램의 각 항목에 레이블을 붙입니다.
+ - 청중이 모호하게 느낄 수 있는 항목에는 반드시 레이블을 추가합니다.
+- **색상**
+ - 색상을 활용하여 서로 다른 상태를 명확히 나타내고, 아티팩트를 구분하기 쉽습니다.
+ - ex) 서로 다른 마이크로서비스의 인스턴스를 색상으로 구별
+- **키**
+ - 셰이프가 모호할 경우, **다이어그램에 키를 추가해 각 셰이프의 의미를 명확히** 합니다.
+
+## 21.2 프레젠테이션
+
+아키텍트는 PowerPoint나 Keynote 같은 프레젠테이션 도구를 효과적으로 활용하는 능력이 필요합니다.
+문서와 프레젠테이션에는 시간 조작이라는 근본적인 차이가 있다는 점에 주목할 필요가 있습니다.
+프레젠테이션에서 발표자는 아이디어 전개의 속도를 스스로 조절할 수 있지만, 문서는 독자가 속도를 조절합니다.
+시간을 효과적으로 관리해야 프레젠테이션에서 성공할 수 있습니다.
+
+### 21.2.1 시간 조작
+
+프레젠테이션 도구는 **전환(transition)**과 **애니메이션(animation)**을 통해 슬라이드의 시간을 조작합니다.
+
+- **전환**: 한 슬라이드에서 다른 슬라이드로 이동합니다.
+- **애니메이션**: 슬라이드 내 요소에 움직임을 부여합니다. 나타내기, 사라지기, 이동, 크기 조정 등 다양한 동적 효과를 포함합니다.
+
+한 슬라이드를 과도하게 채우지 말고, **아이디어를 여러 슬라이드로 나누어 표현**하고, **전환과 애니메이션을 활용해 자연스럽게 연결**하는 것이 중요합니다.
+`디졸브`와 같은 전환 효과를 활용하면 슬라이드 경계를 감추며 스토리를 전달할 수 있고, 주제 전환 시에는 `도어`, `큐브` 같은 전환 효과로 새로운 주제를 시각적으로 알릴 수 있습니다.
+
+### 21.2.2 점진적 빌드
+
+**총알투성이 시체(Bullet-Riddled Corpse)**라는 안티패턴은 **텍스트로 가득 찬 슬라이드를 청중에게 보여주고 발표자가 이를 읽는 방식의 프레젠테이션**을 말합니다.
+청중은 이미 슬라이드를 읽고, 발표자의 느린 설명을 수동적으로 듣게 되어, 지루함을 느낄 수밖에 없습니다.
+발표자는 **구두(언어)**, **시각** 두 가지 정보 채널을 통해 슬라이드를 점진적으로 빌드하여, **필요한 정보만 단계적으로 제시**해야 합니다.
+
+예를 들어 기능 브랜칭을 주제로 프레젠테이션을 만들 때, 브랜치를 오래 유지하면 부정적인 결과를 초래한다는 메시지를 전달하려고 합니다.
+이 때 전체 슬라이드를 즉시 보여주면, 청중이 결말을 예상하게 되고, 발표자가 설명할 때까지 이를 기다려야 합니다.
+그 대신, 흰색 상자로 일부 그림을 가린 후 점진적 빌드와 빌드 아웃 애니메이션을 활용해 일부분만 순차적으로 보여주면, 청중에게 기대감과 긴장감을 줄 수 있습니다.
+이를 통해 발표를 더욱 흥미롭고 매력적으로 만들 수 있습니다.
+
+
+
+### 21.2.3 인포덱스 VS 프레젠테이션
+
+프레젠테이션을 청중에게 직접 보여주지 않고, 이메일로 전달해 각자가 읽도록 하는 방식도 있습니다.
+`인포덱스`는 **프레젠테이션 도구를 데스크탑 출판 도구처럼 활용해 정보를 시각적으로 요약**해줍니다.
+
+인포덱스와 프레젠테이션의 주요 차이점에는 **콘텐츠의 종합성**과 **전환/애니메이션 효과**에 있습니다.
+인포덱스는 독자가 잡지 기사처럼 훑어보는 자료로, 시간 요소 없이 모든 정보를 포함시켜서 구성합니다.
+반면, 프레젠테이션은 슬라이드에 일부 정보만 담고 나머지는 발표자가 직접 설명하기 때문에, 전달 방식이 구두 발표에 의존합니다.
+
+### 21.2.4 슬라이드는 절반의 스토리
+
+주요 논점을 강조하려다 과도한 자료를 슬라이드에 넣는 경우가 많습니다.
+**발표자는 슬라이드와 구두 설명이라는 두 가지 정보 채널을 전략적으로 활용해 메시지의 효과를 극대화**해야 합니다.
+`불가시성 전략`은 이러한 접근법의 좋은 사례입니다.
+
+### 21.2.5 불가시성
+
+**불가시성(Invisibility)** 은 발표자에게만 청중의 주목이 집중되도록 **슬라이드에 빈 검정 화면을 삽입**하는 전략입니다.
+핵심 요점을 전달할 때 이 방법을 활용하면, 청중의 관심을 자연스럽게 발표자에게 집중시킬 수 있습니다.
diff --git "a/ch21_\354\225\204\355\202\244\355\205\215\354\262\230_\353\217\204\354\213\235\355\231\224_\353\260\217_\355\224\204\353\240\210\354\240\240\355\205\214\354\235\264\354\205\230/ch21_eden/21-1.png" "b/ch21_\354\225\204\355\202\244\355\205\215\354\262\230_\353\217\204\354\213\235\355\231\224_\353\260\217_\355\224\204\353\240\210\354\240\240\355\205\214\354\235\264\354\205\230/ch21_eden/21-1.png"
new file mode 100644
index 0000000..dad940c
Binary files /dev/null and "b/ch21_\354\225\204\355\202\244\355\205\215\354\262\230_\353\217\204\354\213\235\355\231\224_\353\260\217_\355\224\204\353\240\210\354\240\240\355\205\214\354\235\264\354\205\230/ch21_eden/21-1.png" differ
diff --git "a/ch21_\354\225\204\355\202\244\355\205\215\354\262\230_\353\217\204\354\213\235\355\231\224_\353\260\217_\355\224\204\353\240\210\354\240\240\355\205\214\354\235\264\354\205\230/ch21_eden/21-4.png" "b/ch21_\354\225\204\355\202\244\355\205\215\354\262\230_\353\217\204\354\213\235\355\231\224_\353\260\217_\355\224\204\353\240\210\354\240\240\355\205\214\354\235\264\354\205\230/ch21_eden/21-4.png"
new file mode 100644
index 0000000..5f6bd46
Binary files /dev/null and "b/ch21_\354\225\204\355\202\244\355\205\215\354\262\230_\353\217\204\354\213\235\355\231\224_\353\260\217_\355\224\204\353\240\210\354\240\240\355\205\214\354\235\264\354\205\230/ch21_eden/21-4.png" differ
diff --git "a/ch22_\352\260\234\353\260\234\355\214\200\354\235\204_\355\232\250\354\234\250\354\240\201\354\234\274\353\241\234/ch22_eden.md" "b/ch22_\352\260\234\353\260\234\355\214\200\354\235\204_\355\232\250\354\234\250\354\240\201\354\234\274\353\241\234/ch22_eden.md"
new file mode 100644
index 0000000..b0b7a62
--- /dev/null
+++ "b/ch22_\352\260\234\353\260\234\355\214\200\354\235\204_\355\232\250\354\234\250\354\240\201\354\234\274\353\241\234/ch22_eden.md"
@@ -0,0 +1,267 @@
+# 개발팀을 효율적으로
+
+아키텍트는 기술 아키텍처를 정립하고 결정할 뿐만 아니라, **개발팀이 이를 올바르게 구현하도록 지원**해야 합니다.
+폐쇄적인 환경에서 독단적으로 아키텍처을 작업할 경우 개발팀이 구현 과정에서 어려움을 겪게 됩니다.
+이번 장에는 개발팀을 생산적으로 만들기 위한 기본적인 테크닉을 다룹니다.
+
+## 22.1 팀 경계
+
+개발팀이 아키텍트와 아키텍처로부터 멀어지면, **시스템의 제약 조건에 대한 이해와 경험 부족**으로 인해 아키텍처를 제대로 구현하지 못하는 경우가 많습니다.
+아키텍트는 개발팀이 **아키텍처 구현과 관련된 제약조건과 틀**을 통해 개발팀과 소통합니다.
+이 경계가 너무 빡빡하거나 느슨해지면 개발팀의 아키텍처 구현 능력에 부정적인 영향을 미칠 수 있습니다.
+아키텍트가 제약조건을 과도하게 설정하면, 개발자는 필요한 도구와 라이브러리를 활용하지 못해 효과적으로 시스템을 구현할 수 없습니다.
+반대로 제약이 너무 느슨하거나 아예 없는 경우, 중요한 아키텍처 결정을 개발팀이 떠맡아야 하고, 명확한 지침이 없어 비생산적이게 됩니다.
+
+아키텍트는 팀이 올바른 도구와 라이브러리를 통해 아키텍처를 잘 구현할 수 있도록, 적절한 지침과 제약조건을 제공해야 합니다.
+
+## 22.2 아키텍트 성향
+
+아키텍트는 3가지 유형을 보이며, `내 맘대로 아키텍트`는 빡빡한 경계, `유체이탈 아키텍트`는 느슨한 경계, `유능한 아키텍트`는 적합한 경계를 설정하는 특징이 있습니다.
+
+### 22.2.1 내 맘대로 아키텍트
+
+`내 맘대로 아키텍트(Control Freak Architect)` 는 **소프트웨어 개발의 세부 사항까지 지나치게 통제**하려는 경향이 있습니다.
+이들은 오픈 소스나 서드파티 라이브러리 사용을 제한하고, 명명 규칙, 클래스 설계, 메서드 길이 등을 엄격히 제한하며, 심지어 의사코드까지 제시하는 등 과도한 간섭을 합니다.
+이러한 통제는 개발자들이 아키텍트에 대한 존중을 잃게 만듭니다.
+특히 개발자에서 아키텍트로 전향한 경우, 개발자 역할에 익숙해 컴포넌트 설계와 구현에까지 관여하고 싶어지기 쉽습니다.
+그러나 구현 방안을 결정하는 건 개발자의 역할임을 명심해야 합니다.
+아키텍트는 시스템의 컴포넌트 별 핵심 기능과 컴포넌트간 상호작용을 정의하는 선에서 역할을 다 해야 합니다.
+
+### 22.2.2 유체이탈 아키텍트
+
+유체이탈 아키텍트는 코딩 경험이 부족하거나 세부 구현 사항에 무관심한 아키텍트로, 아키텍처 초안만 완성한 뒤 개발팀과 소통 없이 다른 프로젝트로 떠납니다.
+유체이탈 아키텍트는 기술이나 비즈니스 측면에서 팀을 리드하거나 가이드하기 어렵습니다.
+아키텍트는 다이어그램과 설계를 주로 다루게 되는데, 아키텍트의 경험과 소통이 부족하면 다이어그램이 실제로 실행 가능한지 확인하기 어렵습니다.
+
+예를 들어 주식 거래 시스템 같은 복잡한 솔루션을 설계할 때, 다음과 같이 지나치게 고수준의 다이어그램만 작성하면 세부 구현에 대한 구체성이 부족하게 되어, 개발에 실질적인 도움이 되지 않는다는 한계가 있습니다.
+
+
+
+또한 유체이탈 아키텍트는 개발팀과의 소통과 역할 분담에 소홀하여, 개발팀이 아키텍트의 일을 대신하게 만듭니다.
+이로 인해 프로젝트 진척과 생산성이 떨어지고, 시스템 작동 방식을 이해하는데 혼란이 발생합니다.
+개발팀은 아키텍트의 기술적 지원, 가이드, 그리고 기술·비즈니스 관련 문의에 대한 답변을 필요로 합니다.
+
+다음은 유체이탈 아키텍트의 징후들입니다.
+
+- 비즈니스 영역, 비즈니스 문제, 기술을 온전히 이해하지 못한다.
+- 소프트웨어 개발 실무 경력이 부족하다.
+- 아키텍처 솔루션 구현에 함축된 의미를 전혀 신경 쓰지 않는다.
+
+### 22.2.3 유능한 아키텍트
+
+유능한 소프트웨어 아키텍트는 개발팀에 **명확한 제약조건과 경계를 설정**하고, **협력을 독려**하며 **적절한 가이드를 제공**합니다.
+또한, **팀이 필요한 도구와 기술을 갖췄는지 확인**하고, **장애 요소를 제거해 목표 달성을 지원**합니다.
+개발팀과 긴밀히 협력하며 존경을 얻는 리더십은 하나의 예술이라 할 수 있습니다.
+
+## 22.3 얼마나 제어해야 하나?
+
+유능한 소프트웨어 아키텍트는 개발팀을 적절히 제어할 줄 알아야 합니다.
+이는 다음의 다섯 가지 핵심 팩터에 따라 달라지며, 해당 팩터들은 아키텍트가 한 번에 관리할 수 있는 팀이나 프로젝트의 범위를 결정합니다.
+
+- **팀원 간 친밀도**
+ - 팀원들이 서로 얼마나 잘 알고 있는지, 이전에 함께 프로젝트를 진행한 경험이 있는지
+ - 팀원 간 친밀도가 높을수록, 이미 자율적으로 조직화되기 시작하므로 제어가 덜 필요.
+ - 친밀도가 낮을수록 협업 촉진과 파벌 방지를 위해 더 많은 제어가 필요.
+- **팀 규모**
+ - 팀에 몇 명의 개발자가 있는가?
+ - **작은 팀**: 4명 이하
+ - **큰 팀**: 12명 이상
+ - 팀 규모가 클수록 제어가 더 많이 필요.
+ - 팀 규모가 작을수록 제어가 덜 필요.
+- **전체적인 경험**
+ - 팀원 중 시니어/주니어 개발자의 비율은 어느 정도이고, 기술 및 비즈니스 영역에 대한 팀원들의 숙련도는 어느 정도인가?
+ - **주니어 개발자가 많은 팀**: 제어와 멘토링이 더 필요.
+ - **시니어 개발자가 많은 팀**: 제어가 덜 필요하며, 아키텍트는 멘토보다 조정자(facilitator) 역할에 집중.
+- **프로젝트 복잡도**
+ - 프로젝트의 복잡성은 얼마나 높은가?
+ - **복잡한 프로젝트**: 아키텍트가 팀에 더 많이 관여하고 더 많은 제어 필요.
+ - **단순한 프로젝트**: 별도의 많은 제어 없이 진행 가능.
+- **프로젝트 기간**
+ - 프로젝트의 기간은 얼마나 되는가? - **짧은 프로젝트**: 2개월, **보통 프로젝트**: 6개월, **긴 프로젝트**: 2년 이상
+ - **긴 프로젝트**: 더 많은 제어가 필요.
+ - **짧은 프로젝트**: 제어가 덜 필요.
+
+단기 프로젝트(예: 2개월)는 일정이 빠듯해서 개발팀은 이미 압박을 느껴 효율적으로 작업하기 때문에, 아키텍트가 지나치게 개입하면 오히려 방해가 될 수 있습니다.
+반대로 장기 프로젝트(예: 2년)는 초기 단계에서 긴박감이 적어, 개발자들이 느긋해질 가능성이 있으므로, 아키텍트가 프로젝트를 적시에 진행시키기 위해 더 많은 제어와 관리가 필요합니다.
+
+프로젝트 초기에 팩터들을 기반으로 제어 수준을 결정한 뒤, 프로젝트 진행에 따라 제어 수준도 점진적으로 조정해야 합니다.
+이를 위해 각 팩터에 20점 단위로 값을 매겨 평가하고, 최종 결과가 음수(-) 이면 제어를 덜 해야 함, 양수(+) 이면 제어를 더 해야 함을 나타내는 것으로 정의할 수 있습니다.
+프로젝트 진행 중 지속적으로 지표를 분석해, 적절한 제어 수준을 유지하는 것이 중요합니다.
+
+예를 들어 프로젝트 시나리오에서 각 팩터를 평가한 결과, 각 팩터마다 점수(+20, -20)가 부여되었고, 최종적으로 누적 점수가 -60점으로 나타났습니다.
+이는 아키텍트가 개발팀의 업무를 가급적 방해하지 않고, 자율적으로 진행하도록 하는 것이 바람직함을 의미합니다.
+이 경우 유능한 소프트웨어 아키텍트라면, 초기에는 조정자 역할을 수행하며, 팀원들의 업무에 깊이 개입하지 않습니다.
+그 대신 질문에 답변하고, 프로젝트가 정상적으로 진행되는지 확인하면서, 숙련된 팀원들이 각자의 전문성을 발휘해 소프트웨어 개발을 신속히 진행할 수 있도록 지원합니다.
+
+| 팩터 | 평가 기준 | 평점 |
+| --------------- | ------------- | ---- |
+| 팀원 간 친밀도 | 신규 팀원들 | +20 |
+| 팀 규모 | 작음 (4명) | -20 |
+| 전체적인 경험도 | 모두 유경험자 | -20 |
+| 프로젝트 복잡도 | 비교적 단순함 | -20 |
+| 프로젝트 기간 | 2개월 | -20 |
+| **총합** | | -60 |
+
+이와 달리 이번 시나리오에서는 팀 규모가 크고(12명), 팀원들은 친밀하지만 대부분 주니어 개발자로 구성되어 있습니다.
+프로젝트는 6개월 동안 진행되며, 복잡도는 꽤 복잡한 수준입니다.
+누적 점수는 -20점으로 계산되었으며, 이에 따라 아키텍트는 팀 업무에 일정 부분 관여하여 멘토와 코치 역할을 수행하는 것이 더 효과적이라는 결론이 도출됩니다.
+
+| 팩터 | 평가 기준 | 평점 |
+| --------------- | ----------------- | ---- |
+| 팀원 간 친밀도 | 서로 잘 아는 사이 | -20 |
+| 팀 규모 | 큼 (12명) | +20 |
+| 전체적인 경험도 | 대부분 주니어급 | +20 |
+| 프로젝트 복잡도 | 아주 복잡함 | +20 |
+| 프로젝트 기간 | 6개월 | -20 |
+| **누적 점수** | | -20 |
+
+## 22.4 팀의 이상 징후
+
+팀 규모는 아키텍트의 제어 수준에 영향을 미치는 중요한 요인입니다.
+팀이 클수록 더 많은 제어가 필요하며, 작을수록 제어가 줄어듭니다.
+**효율적인 개발팀의 규모**는 다음 세 가지 요인에 의해 결정됩니다:
+
+- 프로세스 손실
+- 다원적 무지
+- 책임 확산
+
+#### 프로세스 손실
+
+**프로세스 손실(Process Loss)**은 프로젝트에 인력을 더 많이 투입할수록 프로젝트 완료 시간이 길어지는 현상을 의미합니다.
+팀의 **그룹 잠재력(Group Potential)**은 팀원들의 집합적 노력으로 정의되지만, **실제 생산성은 이 잠재력에 미치지 못하며**, 이 차이가 바로 프로세스 손실입니다.
+
+아키텍트는 팀을 관찰하여 프로세스 손실을 식별하고, 이를 통해 적절한 팀 규모를 결정해야 합니다.
+예를 들어, 코드 커밋 과정에서 **병합 충돌**이 자주 발생하면, 이는 팀원들이 동일한 코드 작업을 하며 발이 엉키고 있다는 신호입니다.
+이를 방지하려면 **팀 내에서 병렬 작업이 가능한 부분을 찾아 각자 다른 영역에서 작업**할 수 있도록 해야 합니다.
+팀원이 새로 합류했는데도 병렬 작업 흐름에 기여할 여지가 없다면, 신규 인력이 프로젝트에 부정적 영향을 미칠 수 있음을 설명해야 합니다.
+
+#### 다원적 무지
+
+팀 규모가 너무 커지면 **다원적 무지(Pluralistic Ignorance)** 현상이 발생할 수 있습니다.
+이는 **팀원들이 개인적으로 반대 의견을 가지고 있지만, 뻔한 것을 놓치고 있다고 비난받을까 두려워 마지못해 동의**하는 상황을 말합니다.
+
+예를 들어, 큰 팀에서 대부분의 팀원이 두 원격 서비스가 메시징으로 통신해야 한다고 생각하지만, 한 팀원은 보안 방화벽 문제로 비현실적이라고 판단합니다.
+그러나 비난받을까 두려워 의견을 말하지 않고 동의하게 되고, 결국 메시징이 불가능하다는 사실이 나중에 밝혀져 개발을 다시 하게 됩니다.
+팀 규모가 작았다면 초기 단계에서 문제를 지적하고 대안을 논의하기 더 수월했을 것입니다.
+
+아키텍트는 회의나 토론에서 참가자의 표정과 몸짓을 관찰하여, **다원적 무지가 발생할 조짐이 보이면 조정자로 나서야** 합니다.
+중간중간 논의된 해결책에 대해 팀원들에게 의견을 묻고, 그들이 발언할 때 지지해줌으로써 **자유롭게 의견을 낼 수 있는 분위기를 조성**합니다.
+
+#### 책임 확산
+
+적절한 팀 규모를 결정하는 세 번째 요인은 **책임 확산**입니다.
+의사소통이 어려워지고, 팀원들 간에 누가 어떤 업무를 담당하는지 혼란스러워진다면, 이는 팀이 너무 커졌다는 신호입니다.
+
+## 22.5 체크리스트 활용
+
+체크리스트는 문제를 해결하고 업무를 철저히 준비하는 데 효과적인 도구입니다.
+다만 소프트웨어 개발의 모든 작업에 체크리스트가 필요하지는 않습니다.
+개발팀의 효율성을 높이기 위해서는 **체크리스트를 활용해야 할 상황과 그렇지 않을 상황을 명확히 구분**하는 것이 중요합니다.
+
+체크리스트에는 잇따라 실행되는 종속적인 작업이나, 간단하고 빈번하게 실행되는 프로세스는 포함되지 않아야 합니다.
+예를 들어 아래의 데이터베이스 체크리스트에는 `폼작성 및 전달` 같은 종속적인 작업들이 포함되어 있고, `생성된 테이블 확인` 처럼 간단한 작업도 포함되어 있습니다.
+
+- [ ] 데이터베이스 컬럼 필드명과 타입을 결정한다
+- [ ] 데이터베이스 테이블 요청 폼을 작성한다
+- [ ] 새 데이터베이스 테이블의 퍼미션을 얻는다
+- [ ] 데이터베이스 그룹에 요청 폼을 전달한다
+- [ ] 생성된 테이블을 확인한다
+
+체크리스트는 단순히 작업 단계를 나열하는 것이 아니라, 중요한 확인 사항을 효율적으로 관리하는 데 초점을 맞춰야 합니다.
+순서나 종속 작업이 없으며, 에러가 발생하기 쉽거나 누락되기 쉬운 작업들을 포함해야 합니다.
+이 때, 너무 복잡하거나 방대한 체크리스트는 개발자들이 활용하지 않을 가능성이 높기 때문에, 모든 것을 체크리스트로 만들려 하지 않아야 합니다.
+
+경험 상 가장 효과적인 체크리스트 3가지는 다음과 같습니다.
+
+1. 개발자 코드 완료 체크리스트
+2. 단위/기능 테스트 체크리스트
+3. 소프트웨어 릴리스 체크리스트
+
+### 22.5.1 개발자 코드 완성도 체크리스트
+
+`개발자 코드 완성도 체크리스트`는 개발자가 코드 작업을 ‘완료’했음을 판단하는 도구이며, 다음 내용이 포함됩니다:
+
+- 자동화 도구에 포함되지 않은 코딩 및 포매팅 표준
+- 자주 간과되는 항목(예: 로그에 숨겨진 오류)
+- 프로젝트별 표준
+- 팀의 특별 지침이나 절차
+
+예시는 다음과 같습니다.
+
+- [ ] 코드를 깨끗이 정리하고 포매팅한다.
+- [ ] 커스텀 소스 검증 도구를 실행한다.
+- [ ] 모든 업데이트에 감사 로그가 기록됐는지 확인한다.
+- [ ] 예외가 묻혀버리는 코드가 없는지 검사한다.
+- [ ] 하드코딩된 값이 있는지 체크해서 상수로 바꾼다.
+- [ ] 블릭 메서드만 `setFailure()`를 호출하는지 확인한다.
+- [ ] 서비스 API 클래스에 `@ServiceEntrypoint`를 붙인다.
+
+체크리스트는 코드 정리와 포매팅, 예외 처리 확인 같은 기본적이고 명확한 항목을 포함합니다.
+기본적인 작업도 종종 놓치는 경우가 있기 때문에, 당연히 해야 할 일도 체크리스트로 관리하는 것이 중요합니다.
+
+2, 3, 6, 7번 항목은 프로젝트에 특정한 태스크로, 체크리스트에 포함하기 적합하지만, 체크 작업을 자동화하거나 플러그인 기반 유효성 검증기로 대체하여 체크리스트의 분량을 줄이는 것이 좋습니다.
+예를 들어, setFailure() 호출을 체크하는 것은 IDE에서 자동화가 가능합니다.
+
+### 22.5.2 단위
+
+`단위/기능 테스트 체크리스트`는 엣지 케이스와 같이 개발자가 놓치기 쉬운 테스트와, QA팀이 발견한 테스트 이슈 등 모든 종류의 테스트를 포괄합니다.
+이 체크리스트의 목표는 가능한 완전한 코드를 보장하여, 프로덕션 배포가 가능한 상태로 만드는 것입니다.
+
+체크리스트에는 다음 항목들이 포함됩니다:
+
+- 텍스트 필드의 특수 문자와 숫자 필드 확인
+- 최솟값/최댓값 범위 검증
+- 드물고 극단적인 테스트 케이스 확인
+- 누락된 필드 처리 확인
+
+자동화 테스트로 확인 가능한 항목은 체크리스트에서 제거해야 합니다.
+예를 들어, 주식 거래 앱에서 매입 주식 수의 마이너스 여부를 테스트하는 로직이 테스트 스위트에 포함되어 있다면, 해당 항목은 체크리스트에서 제외합니다.
+
+단위/기능 테스트 체크리스트는 개발자가 수행해야 하는 단위 테스트의 방법과 범위를 명확히 합니다.
+체크리스트를 통해 테스트 시나리오가 소프트웨어 개발 프로세스에 포함되었는지 확인할 수 있어, 테스트팀은 체크리스트에 없는 비즈니스 시나리오에 집중할 수 있습니다.
+
+### 22.5.3 소프트웨어 릴리스 체크리스트
+
+소프트웨어 릴리스는 개발 라이프 사이클에서 에러가 발생하기 가장 쉬운 단계입니다.
+체크리스트 작성을 통해 빌드 및 배포 실패를 방지하고 출시 관련 리스크를 줄일 수 있습니다.
+릴리스 체크리스트는 배포 중 발생하는 에러와 이슈를 해결하며 지속적으로 업데이트되므로, 변화가 많이 발생합니다.
+
+체크리스트에는 일반적으로 다음 내용이 포함됩니다:
+
+- 서버 또는 외부 구성 서버의 설정 변경
+- 프로젝트에 추가된 서드파티 라이브러리(JAR, DLL 등) 확인
+- 데이터베이스 업데이트 및 마이그레이션 스크립트 점검
+
+## 22.6 지침 제시
+
+소프트웨어 설계 원칙을 명확히 전달하는 것은 팀의 성공에 중요한 요소입니다.
+아키텍트는 애플리케이션에서 사용 가능한 서드파티 라이브러리에 대한 지침을 제공하여, 개발팀이 사용 가능한 라이브러리와 금지된 라이브러리를 명확히 구분하도록 도와야 합니다.
+다음의 두 질문을 통해 지침을 제시할 수 있습니다.
+
+1. 제안하신 라이브러리와 기존 시스템의 내부 기능 사이에 중첩돠는 부분이 있나요?
+2. 제안하신 라이브러리를 반드시 사용해야 하는 당위성은 무엇인가요?
+
+첫번째 질문은 개발자가 기존 라이브러리나 기능으로도 충족이 가능한지를 검토하도록 유도하여, 프로젝트에서 기능 중복 문제를 예방합니다.
+두번째 질문은 새 라이브러리 도입의 기술적 및 비즈니스적 타당성을 모두 검토하도록 요구하여, 비즈니스적 정당화의 중요성을 인식시킵니다.
+
+개발팀이 **결정 가능한 사항과 불가능한 사항을 시각적으로 설명**하면 설계 원칙을 효과적으로 전달할 수 있습니다.
+다음 예시는 레이어드 스택 구조를 시각화하여, 서드파티 라이브러리의 각 범주에 무엇이 포함되는지, 개발자가 무엇을 할 수 있고 무엇을 할 수 없는지를 보여줍니다.
+
+![](./ch22_eden/22-13.png)