Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

Appendix C. 동적인 협력, 정적인 코드

"정적 모델은 동적 모델 위에 세워져야 한다. 행동이 코드를 결정한다."

📌 핵심 개념

이 장에서는 동적 모델과 정적 모델의 관계를 다룹니다. 객체의 협력(동적 모델)이 코드 구조(정적 모델)를 주도해야 하며, 도메인 모델은 출발점일 뿐 코드가 협력에 맞춰 진화해야 함을 학습합니다.

🎯 학습 목표

  • 동적 모델과 정적 모델의 차이 이해하기
  • 행동이 코드를 결정하는 과정 학습하기
  • 도메인 모델의 올바른 역할 파악하기
  • 분석/설계/구현 모델의 통합 이해하기
  • TYPE OBJECT 패턴 학습하기
  • 협력 중심 설계의 중요성 깨닫기

📖 목차

  1. 동적 모델과 정적 모델
  2. 행동이 코드를 결정한다
  3. 도메인 모델과 구현
  4. TYPE OBJECT 패턴
  5. 분석, 설계, 구현의 통합
  6. 핵심 정리

1. 동적 모델과 정적 모델

1.1 두 가지 모델

🎯 핵심 정의

┌─────────────────────────────────────────────────────┐
│                                                     │
│  동적 모델 (Dynamic Model):                           │
│  프로그램의 실행 구조를 표현하는 움직이는 모델                 │
│                                                     │
│  구성 요소:                                           │
│  - 객체 (Objects)                                    │
│  - 협력 (Collaborations)                             │
│  - 메시지 (Messages)                                  │
│  - 런타임 행동 (Runtime Behavior)                      │
│                                                     │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│                                                     │
│  정적 모델 (Static Model):                            │
│  코드의 구조를 담는 고정된 모델                            │
│                                                     │
│  구성 요소:                                           │
│  - 타입 (Types)                                      │
│  - 관계 (Relationships)                              │
│  - 클래스 구조 (Class Structure)                       │
│  - 컴파일 타임 구조 (Compile-time Structure)            │
│                                                     │
└─────────────────────────────────────────────────────┘

📊 비교표

측면 동적 모델 정적 모델
본질 실행 중인 프로그램 소스 코드
초점 행동과 협력 타입과 관계
시점 런타임 컴파일 타임
표현 객체와 메시지 클래스와 인터페이스
변화 동적 (계속 변함) 정적 (고정됨)
목적 What (무엇을) How (어떻게)

1.2 모델 간의 관계

🎯 주도권은 동적 모델에

┌─────────────────────────────────────────────────────┐
│                                                     │
│  정적 모델은 동적 모델에 의해 주도되어야 한다                  │
│                                                     │
│  동적 모델 (객체 협력)                                  │
│        ↓                                            │
│  정적 모델 (코드 구조)                                  │
│                                                     │
│  행동이 타입을 결정한다!                                  │
│                                                     │
└─────────────────────────────────────────────────────┘

왜 동적 모델이 우선인가?

1. 소프트웨어의 목적 = 행동 제공
   → 행동이 본질

2. 타입은 행동을 분류하는 도구
   → 수단일 뿐

3. 협력이 설계의 중심
   → 협력에 맞는 타입 필요

4. 변경은 행동에서 시작
   → 행동 변경에 따라 타입 진화

🔄 모델 간 상호작용

동적 모델:
"사용자가 영화를 예매한다"
"할인 정책에 따라 가격을 계산한다"
"상영 시간을 확인한다"

     ↓ 영향

정적 모델:
class Movie { ... }
interface DiscountPolicy { ... }
class Screening { ... }

     ↓ 구현

동적 모델 실현:
new Movie(...).calculateFee(screening)
discountPolicy.calculateDiscount(...)

1.3 프로그래머의 두 가지 사고

┌─────────────────────────────────────────────────────┐
│                                                     │
│  프로그래머는 두 가지 모델을 동시에 그려야 한다                │
│                                                     │
│  1. 동적 모델 (런타임 협력)                              │
│     - 객체들이 어떻게 협력하는가?                          │
│     - 어떤 메시지를 주고받는가?                           │
│     - 책임이 어떻게 분배되는가?                           │
│                                                     │
│  2. 정적 모델 (코드 구조)                                │
│     - 어떤 클래스가 필요한가?                             │
│     - 클래스 간 관계는 무엇인가?                          │
│     - 타입 계층은 어떻게 구성하는가?                       │
│                                                     │
│  그리고 동적 모델이 정적 모델을 주도하게 한다!                 │
│                                                     │
└─────────────────────────────────────────────────────┘

2. 행동이 코드를 결정한다

2.1 행동 우선의 원칙

🎯 핵심 원칙

┌─────────────────────────────────────────────────────┐
│                                                     │
│  가장 중요한 것은                                       │
│  객체가 외부에 제공하는 행동이다                            │
│                                                     │
│  행동 → 책임 → 협력 → 타입 → 클래스                       │
│                                                     │
└─────────────────────────────────────────────────────┘

순서:

1단계: 행동 파악
"영화 가격을 계산해야 한다"

2단계: 책임 할당
"Movie가 가격 계산 책임"
"DiscountPolicy가 할인 계산 책임"

3단계: 협력 설계
Movie → DiscountPolicy.calculateDiscount()

4단계: 타입 정의
interface DiscountPolicy { ... }

5단계: 클래스 구현
class AmountDiscountPolicy implements DiscountPolicy { ... }

2.2 잘못된 순서의 문제

❌ 타입 우선 접근

// ❌ 나쁜 접근: 타입부터 생각
// "어떤 클래스가 필요할까?"

class Movie { ... }
class Actor { ... }
class Director { ... }
class Theater { ... }

// 문제:
// - 협력이 없음
// - 책임이 불명확
// - 행동이 정의되지 않음
// - 변경에 취약

문제점:

1. 데이터 중심 설계
   → 캡슐화 위반

2. 책임 불명확
   → 응집도 낮음

3. 협력 부재
   → 결합도 높음

4. 변경 어려움
   → 유지보수 곤란

✅ 행동 우선 접근

// ✅ 좋은 접근: 행동부터 생각
// "무엇을 해야 하는가?"

// 1. 행동 정의
"영화 예매"
"가격 계산"
"할인 적용"

// 2. 책임 할당
Movie: 예매 정보 관리, 가격 계산
Screening: 상영 정보 관리
DiscountPolicy: 할인 계산

// 3. 협력 설계
ScreeningMovieDiscountPolicy

// 4. 타입과 클래스
public class Movie {
    private DiscountPolicy discountPolicy;
    
    public Money calculateMovieFee(Screening screening) {
        return fee.minus(discountPolicy.calculateDiscount(screening));
    }
}

2.3 변경을 고려하라

🎯 변경 주도 설계

┌─────────────────────────────────────────────────────┐
│                                                     │
│  동일한 행동을 제공하는 정적 모델이 여러 개 있다면              │
│  현재의 설계에서 요구되는 변경을                            │
│  부드럽게 수용할 수 있는 설계를 선택하라                      │
│                                                     │
└─────────────────────────────────────────────────────┘

예시: 할인 정책 설계

// 방법 1: 상속 기반
abstract class DiscountPolicy {
    abstract Money calculateDiscount(Screening screening);
}

// 방법 2: 인터페이스 기반
interface DiscountPolicy {
    Money calculateDiscount(Screening screening);
}

// 방법 3: 전략 패턴
class Movie {
    private DiscountStrategy strategy;
}

// 선택 기준:
// - 어떤 변경이 예상되는가?
// - 새로운 할인 정책 추가?
// - 할인 정책 동적 변경?
// - 할인 정책 조합?예상되는 변경에 가장 유연한 방법 선택!

💡 설계 결정 프로세스

1. 행동 정의
   "할인 정책 적용"

2. 예상 변경 파악
   - 새로운 정책 추가 (높음)
   - 정책 동적 변경 (중간)
   - 정책 조합 (낮음)

3. 정적 모델 옵션 생성
   - 인터페이스
   - 추상 클래스
   - 전략 패턴
   - 데코레이터 패턴

4. 변경 시나리오 시뮬레이션
   각 옵션에서 변경이 얼마나 쉬운가?

5. 최적 모델 선택
   가장 유연한 옵션 선택

6. 구현 및 검증
   실제 변경으로 검증

3. 도메인 모델과 구현

3.1 도메인 모델이란?

🎯 정의

도메인 (Domain):
사용자가 프로그램을 사용하는 대상 영역

모델 (Model):
지식을 선택적으로 단순화하고
의식적으로 구조화한 형태

도메인 모델 (Domain Model):
대상 영역에 대한 지식을
선택적으로 단순화하고
의식적으로 구조화한 형태

예시:

도메인: 영화 예매 시스템

도메인 모델:
┌──────────┐      ┌──────────┐
│  영화     │──────│  상영     │
└──────────┘      └──────────┘
     │
     │ 적용
     ▼
┌──────────┐
│ 할인정책   │
└──────────┘
     △
     │
┌────┴────┐
│         │
금액할인  비율할인

3.2 도메인 모델의 역할

💡 출발점이지 목표가 아니다

┌─────────────────────────────────────────────────────┐
│                                                     │
│  도메인 모델은:                                        │
│                                                     │
│  ✅ 시작점                                           │
│  ✅ 힌트 제공                                         │
│  ✅ 개념의 이름과 의미                                  │
│  ✅ 관계에 대한 가이드                                  │
│                                                     │
│  ❌ 최종 목표가 아님                                    │
│  ❌ 코드 구조와 일치 필수 아님                            │
│  ❌ 변경 불가능한 청사진 아님                             │
│                                                     │
└─────────────────────────────────────────────────────┘

중요한 것:

1순위: 소프트웨어의 기능
2순위: 객체의 책임
3순위: 객체의 협력

도메인 모델은 이를 돕는 도구일 뿐!

3.3 도메인 모델과 코드의 괴리

⚠️ 도메인 모델에 집착하지 말라

❌ 잘못된 접근:

도메인 모델:
영화 - 감독 - 배우 - 장르 - 상영관

코드:
class Movie {
    private Director director;
    private List<Actor> actors;
    private Genre genre;
    private Theater theater;
}

문제:
- 협력 없음
- 책임 불명확
- 단순 데이터 저장소

올바른 접근:

✅ 협력 중심 설계:

필요한 협력:
"영화 가격 계산"
"할인 적용"
"상영 시간 확인"

코드:
class Movie {
    private Money fee;
    private DiscountPolicy discountPolicy;
    
    public Money calculateMovieFee(Screening screening) {
        return fee.minus(
            discountPolicy.calculateDiscount(screening)
        );
    }
}

→ 도메인 모델과 다르지만 협력에 적합!

🔄 진화하는 도메인 모델

초기 도메인 모델:
영화 → 할인정책

협력 설계 후:
영화 → 할인정책
  │
  └─→ 할인조건

코드 구현 후:
영화 → 할인정책 → 할인조건
  │
  └─→ 상영

최종 도메인 모델:
영화, 할인정책, 할인조건, 상영의 협력 관계

→ 코드에 맞춰 도메인 모델 진화!

3.4 도메인 모델은 다양한 형태

┌─────────────────────────────────────────────────────┐
│                                                     │
│  도메인 모델 ≠ 클래스 다이어그램                           │
│                                                     │
│  도메인의 핵심을 표현할 수 있는 모든 것:                     │
│                                                     │
│  - 클래스 다이어그램                                     │
│  - 순서도                                             │
│  - 상태 다이어그램                                      │
│  - 협력 다이어그램                                      │
│  - 사용자 스토리                                        │
│  - 시나리오                                            │
│  - 심지어 그림이나 글!                                   │
│                                                     │
└─────────────────────────────────────────────────────┘

4. TYPE OBJECT 패턴

4.1 문제 상황: 몬스터 설계

📝 요구사항

게임에 다양한 몬스터가 등장한다:
- 용 (Dragon): 체력 230, 공격 "불을 내뿜는다"
- 트롤 (Troll): 체력 48, 공격 "곤봉으로 때린다"

새로운 몬스터를 계속 추가해야 한다.

❌ 방법 1: 상속 기반

// Step 01: 클래스 상속
public abstract class Monster {
    private int health;
    
    public Monster(int health) {
        this.health = health;
    }
    
    abstract public String getAttack();
}

public class Dragon extends Monster {
    public Dragon() {
        super(230);
    }
    
    @Override
    public String getAttack() {
        return "용은 불을 내뿜는다";
    }
}

public class Troll extends Monster {
    public Troll() {
        super(48);
    }
    
    @Override
    public String getAttack() {
        return "트롤은 곤봉으로 때린다";
    }
}

문제점:

새로운 몬스터 추가마다:
1. 새로운 클래스 작성
2. 코드 컴파일
3. 배포

→ 클래스 폭발!
→ 유연성 부족!
→ 런타임 변경 불가!

4.2 TYPE OBJECT 패턴

🎯 핵심 아이디어

┌─────────────────────────────────────────────────────┐
│                                                     │
│  TYPE OBJECT 패턴:                                   │
│                                                     │
│  어떤 인스턴스가                                        │
│  다른 인스턴스의 타입을 표현하는 방법                        │
│                                                     │
│  타입을 클래스가 아닌 객체로 표현!                          │
│                                                     │
└─────────────────────────────────────────────────────┘

✅ 방법 2: TYPE OBJECT 패턴

// Step 02: 타입을 객체로!

// 타입을 표현하는 클래스
public class Breed {
    private String name;
    private int health;
    private String attack;

    public Breed(String name, int health, String attack) {
        this.name = name;
        this.health = health;
        this.attack = attack;
    }

    public int getHealth() {
        return health;
    }

    public String getAttack() {
        return attack;
    }
}

// 몬스터 클래스
public class Monster {
    private int health;
    private Breed breed;  // 타입을 객체로!
    
    public Monster(Breed breed) {
        this.breed = breed;
        this.health = breed.getHealth();
    }
    
    public String getAttack() {
        return breed.getAttack();
    }
}

사용:

// 타입 객체 생성
Breed dragonBreed = new Breed("용", 230, "용은 불을 내뿜는다");
Breed trollBreed = new Breed("트롤", 48, "트롤은 곤봉으로 때린다");

// 몬스터 생성
Monster dragon = new Monster(dragonBreed);
Monster troll = new Monster(trollBreed);

System.out.println(dragon.getAttack());  // "용은 불을 내뿜는다"
System.out.println(troll.getAttack());   // "트롤은 곤봉으로 때린다"

4.3 데이터 기반 설정

💾 JSON 설정 파일

{
  "breeds": [
    {
      "name": "",
      "health": 230,
      "attack": "용은 불을 내뿜는다"
    },
    {
      "name": "트롤",
      "health": 48,
      "attack": "트롤은 곤봉으로 때린다"
    },
    {
      "name": "오크",
      "health": 65,
      "attack": "오크는 도끼로 내리친다"
    }
  ]
}

로딩 코드:

public class BreedRepository {
    private Map<String, Breed> breeds = new HashMap<>();
    
    public void loadFromJson(String jsonFile) {
        // JSON 파싱
        JsonArray breedArray = parseJson(jsonFile);
        
        for (JsonObject obj : breedArray) {
            Breed breed = new Breed(
                obj.getString("name"),
                obj.getInt("health"),
                obj.getString("attack")
            );
            breeds.put(breed.getName(), breed);
        }
    }
    
    public Breed getBreed(String name) {
        return breeds.get(name);
    }
}

// 사용
BreedRepository repo = new BreedRepository();
repo.loadFromJson("monster.json");

Monster dragon = new Monster(repo.getBreed("용"));
Monster orc = new Monster(repo.getBreed("오크"));

4.4 TYPE OBJECT 패턴의 장점

✅ 장점:

1. 새로운 타입 추가 용이
   - 코드 수정 없이 데이터만 추가
   - 컴파일 불필요
   - 런타임 로딩 가능

2. 유연성
   - 타입을 동적으로 변경 가능
   - 타입 조합 가능

3. 설정 외부화
   - JSON, XML, DB 등으로 관리
   - 비개발자도 수정 가능

4. 메모리 효율
   - 동일한 타입은 한 번만 생성
   - 여러 인스턴스가 공유

4.5 구조 비교

상속 방식

         Monster (추상)
            △
            │
    ┌───────┼───────┐
    │       │       │
  Dragon  Troll   Orc  ...

- 각 타입마다 클래스 필요
- 컴파일 타임 고정
- 코드 변경 필요

TYPE OBJECT 방식

Monster ─────> Breed
  │              ↑
  │              │
  └─ breed ──────┘

Breed instances:
- dragonBreed
- trollBreed
- orcBreed
...

- 타입 = 데이터
- 런타임 생성 가능
- 설정으로 관리

5. 분석, 설계, 구현의 통합

5.1 세 가지 모델

📋 전통적 구분

분석 모델 (Analysis Model):
- 문제 도메인에 초점
- "무엇을" 해야 하는가
- 요구사항 이해

     ↓

설계 모델 (Design Model):
- 솔루션 도메인에 초점
- "어떻게" 구현할 것인가
- 기술적 관점

     ↓

구현 모델 (Implementation Model):
- 프로그래밍 언어로 표현
- 실제 동작하는 코드

5.2 모델 분리의 문제

❌ 모델 간 괴리

분석 모델:
┌──────────┐      ┌──────────┐
│  고객     │──────│  주문     │
└──────────┘      └──────────┘

설계 모델:
┌──────────┐      ┌──────────┐      ┌──────────┐
│Customer  │──────│  Order   │──────│OrderItem │
└──────────┘      └──────────┘      └──────────┘

구현 모델:
class Customer {
    private List<Order> orders;
}
class Order {
    private List<Item> items;
}

문제:
- 모델 간 불일치
- 개념 불명확
- 유지보수 어려움

5.3 통합된 모델

✅ 하나의 모델

┌─────────────────────────────────────────────────────┐
│                                                     │
│  분석, 설계, 구현은                                     │
│  하나의 모델로 통합되어야 한다                             │
│                                                     │
│  전체 개발 주기 동안                                    │
│  동일한 모델을 유지하라                                  │
│                                                     │
└─────────────────────────────────────────────────────┘

통합 모델:

개념:
영화 예매 시스템에서
영화는 할인 정책을 가진다

분석:
"영화에 할인 정책을 적용한다"

설계:
Movie ─────> DiscountPolicy

구현:
public class Movie {
    private DiscountPolicy discountPolicy;
    
    public Money calculateFee(Screening screening) {
        return fee.minus(
            discountPolicy.calculateDiscount(screening)
        );
    }
}

→ 모든 단계에서 동일한 개념과 구조!

5.4 행동과 변경 중심

🎯 공통 기반

세 모델 모두:

1. 행동에 영향 받음
   - 어떤 기능을 제공하는가
   - 어떤 책임을 가지는가

2. 변경에 영향 받음
   - 어떤 변경이 예상되는가
   - 어떻게 대응할 것인가

→ 행동과 변경이 모델의 중심!

예시:

행동: "할인 정책 적용"
변경: "새로운 할인 정책 추가"

분석:
영화는 다양한 할인 정책을 적용할 수 있다

설계:
Movie는 DiscountPolicy 인터페이스에 의존
다양한 구현체로 확장 가능

구현:
interface DiscountPolicy { ... }
class AmountDiscountPolicy implements DiscountPolicy { ... }
class PercentDiscountPolicy implements DiscountPolicy { ... }

→ 모든 단계에서 동일한 구조!

5.5 객체지향의 장점

┌─────────────────────────────────────────────────────┐
│                                                     │
│  객체지향 패러다임의 가장 큰 장점:                          │
│                                                     │
│  전체 개발 주기 동안                                    │
│  동일한 설계 기법과 모델링 방법을 사용할 수 있다               │
│                                                     │
│  분석 → 설계 → 구현                                    │
│  모두 객체와 협력으로 표현!                               │
│                                                     │
└─────────────────────────────────────────────────────┘

5.6 실천 방법

💡 통합 모델 만들기

1. 도메인 이해부터 시작
   - 핵심 개념 파악
   - 용어 정리

2. 협력 시나리오 작성
   - 객체들이 어떻게 협력하는가
   - 메시지 흐름은?

3. 책임 할당
   - 누가 무엇을 하는가
   - 정보 전문가는?

4. 타입 정의
   - 협력에 필요한 타입은?
   - 인터페이스는?

5. 클래스 구현
   - 협력을 코드로 구현
   - 변경 고려

6. 모델 진화
   - 코드에 맞춰 도메인 모델 업데이트
   - 피드백 반영

→ 반복하며 모델 정제!

6. 핵심 정리

🎯 동적 vs 정적 모델

모델 본질 구성 요소 역할
동적 모델 실행 구조 객체, 협력 행동 정의
정적 모델 코드 구조 타입, 관계 구현 지원

📊 핵심 원칙

1. 동적 모델이 정적 모델을 주도
   → 행동이 타입을 결정

2. 행동이 코드를 결정
   → 협력 먼저, 타입은 나중

3. 변경을 고려하라
   → 유연한 설계 선택

4. 도메인 모델은 출발점
   → 협력에 맞춰 진화

5. 분석/설계/구현 통합
   → 하나의 모델 유지

💡 핵심 프로세스

┌─────────────────────────────────────────────────────┐
│                                                     │
│  1. 행동 파악 (What)                                  │
│     "무엇을 해야 하는가?"                               │
│                                                     │
│  2. 협력 설계 (How - 동적)                             │
│     "객체들이 어떻게 협력하는가?"                          │
│                                                     │
│  3. 변경 고려 (When)                                  │
│     "어떤 변경이 예상되는가?"                             │
│                                                     │
│  4. 타입 정의 (What - 정적)                            │
│     "어떤 타입이 필요한가?"                              │
│                                                     │
│  5. 클래스 구현 (How - 정적)                            │
│     "어떻게 구현할 것인가?"                              │
│                                                     │
│  6. 검증 및 진화                                       │
│     "협력이 잘 동작하는가?"                              │
│     "모델을 개선할 수 있는가?"                            │
│                                                     │
└─────────────────────────────────────────────────────┘

🎓 실전 가이드

Do's ✅

1. 행동부터 생각하라
   - "무엇을 해야 하는가?"
   - 객체의 책임은?

2. 협력을 설계하라
   - 객체들이 어떻게 협력?
   - 메시지 흐름은?

3. 변경을 고려하라
   - 어떤 변경이 예상?
   - 유연한 설계는?

4. 도메인 모델을 진화시켜라
   - 코드에 맞춰 업데이트
   - 협력 반영

5. TYPE OBJECT 패턴 활용
   - 타입이 많고 자주 변경되면
   - 데이터로 타입 표현

6. 모델을 통합하라
   - 분석/설계/구현 일치
   - 하나의 언어 사용

Don'ts ❌

1. 타입부터 설계하지 말라
   - 데이터 중심 설계 위험
   - 협력 부재

2. 도메인 모델에 집착하지 말라
   - 코드가 우선
   - 협력에 맞춰 변경

3. 모델을 분리하지 말라
   - 분석 ≠ 설계 ≠ 구현
   - 통합된 모델 유지

4. 정적 모델에 갇히지 말라
   - 협력이 불편하면 변경
   - 타입은 도구일 뿐

5. 클래스부터 만들지 말라
   - 협력 먼저
   - 클래스는 나중

6. 변경을 무시하지 말라
   - 유연성 고려
   - 확장 가능한 설계

🌟 핵심 교훈

1. 동적 모델 → 정적 모델
   → 행동이 타입을 결정

2. 협력이 설계의 중심
   → 객체의 행동에 집중

3. 도메인 모델은 가이드
   → 협력에 맞춰 진화

4. TYPE OBJECT 패턴
   → 타입을 데이터로 표현

5. 분석/설계/구현 통합
   → 하나의 모델로 일관성

6. 변경 주도 설계
   → 유연성이 핵심

7. 객체지향의 본질
   → 객체와 협력

8. 코드는 살아있다
   → 지속적으로 진화

🔑 마무리 메시지

┌─────────────────────────────────────────────────────┐
│                                                     │
│  "정적 모델은 동적 모델의 그림자다"                         │
│                                                     │
│  객체의 협력(동적 모델)이                                 │
│  코드 구조(정적 모델)를 결정한다                           │
│                                                     │
│  도메인 모델은 출발점일 뿐                                │
│  최종 목적지는 동작하는 협력이다                            │
│                                                     │
│  분석, 설계, 구현을 구분하지 말고                          │
│  하나의 통합된 모델로 생각하라                             │
│                                                     │
│  행동과 변경에 집중하라                                   │
│  그러면 좋은 설계가 자연스럽게 나온다                        │
│                                                     │
└─────────────────────────────────────────────────────┘

📈 실무 적용

프로젝트 시작할 때:

1. 도메인 이해
   - 핵심 개념 파악
   - 전문가와 대화

2. 협력 시나리오 작성
   - 사용자 스토리
   - 유스케이스

3. 객체 식별
   - 책임 할당
   - 협력 설계

4. 프로토타입 작성
   - 핵심 협력 구현
   - 검증

5. 반복 개선
   - 피드백 수렴
   - 모델 진화

→ 전체 과정에서 동일한 모델 유지!

🔗 연결고리

이전 장과의 연결

  • Appendix B: 타입 계층 구현 → 정적 모델
  • 전체 책: 역할, 책임, 협력 → 동적 모델
  • Chapter 2: 객체지향 프로그래밍 → 협력 설계

실무로의 확장

  • 다음 단계:
    • 도메인 주도 설계 (DDD)
    • 이벤트 스토밍
    • 행동 주도 개발 (BDD)
    • 테스트 주도 개발 (TDD)

전체 여정의 마무리

Chapter 1-15 + Appendix A-C:

객체지향의 본질 = 협력

협력을 설계하라 (동적 모델)
    ↓
타입을 정의하라 (정적 모델)
    ↓
코드로 구현하라
    ↓
검증하고 개선하라
    ↓
반복하라

→ 이것이 객체지향!