콘텐츠로 이동

오브젝트 실전 강의 교재

부록 C — 동적인 협력, 정적인 코드

원서: 조영호 『오브젝트』 대상: Java/Spring 백엔드 입문~중급 수강생 형식: 개념 → 비유 → 예시 → 핵심 교훈 → 함정 → 체크리스트 → 퀴즈(정답 분리)


0. 이 장을 시작하기 전에

0.1 학습 목표

  • 동적 모델 (런타임 객체 협력) vs 정적 코드 (클래스·메서드) 의 차이.
  • "행동이 코드를 결정 " — 협력을 먼저 그리고 코드는 그것을 표현.
  • 도메인 모델·분석 모델·설계 모델·구현 모델 의 4 모델 관계.
  • 오브젝트 책 전체의 마지막 통찰.

0.2 큰 그림 — 4 모델의 관계

[ 도메인 (실세계) ]
[ 분석 모델 ]  도메인 전문가의 개념 + 비즈니스 규칙
[ 설계 모델 ]  개발자의 해석 → 클래스·인터페이스·협력
[ 구현 모델 ]  실제 코드
[ 동적 협력 ]  런타임 객체 메시지 흐름

비유 — "건축"

새 도시를 짓는다고 해 봅시다. 건축가는 먼저 도시 전체를 살펴보고 스케치를 그리고, 그 스케치를 설계도로 다듬은 뒤, 설계도를 따라 건물을 시공합니다. 시공이 끝나면 그 안에서 사람들이 오가는 동선이 생깁니다. 그런데 동선은 시공이 끝난 다음에 저절로 정해지는 것이 아닙니다. 사람들이 어떻게 움직일지를 먼저 정하고, 그 동선이 거꾸로 설계와 시공을 이끕니다.

객체지향도 같은 순서입니다. 실세계 도메인이 도시에, 분석 모델이 건축가의 스케치에, 설계 모델이 설계도에, 구현 모델이 시공에, 런타임의 동적 협력이 사람들의 동선에 해당합니다. 코드를 다 짜야 협력이 생기는 것이 아니라, 객체들이 주고받을 협력을 먼저 정하고 그 협력이 코드를 이끌어야 합니다.

0.3 현업에서 왜 중요한가

  • 오브젝트 책 전체 (1~15장) 의 마지막 통찰 — 코드 정적 구조가 본질 X, 동적 협력이 본질.
  • DDD 의 Ubiquitous Language 와 직결 — 4 모델이 한 언어 공유.
  • "왜 도메인 모델이 코드와 어긋나는가" 의 진단.

1. 동적 모델과 정적 모델

1.1 행동이 코드를 결정한다

객체 협력 (동적) 이 먼저, 클래스·메서드 (정적) 는 그것을 표현.

거꾸로 사고하는 함정

[ 잘못된 순서 ]            [ 올바른 순서 ]
 클래스 그리기              협력 시나리오 그리기
   ↓                        ↓
 필드·메서드 설계            메시지·책임 분배
   ↓                        ↓
 협력 발견 안 됨            클래스·필드는 협력의 결과

사례 — 영화 예매

[ 잘못된 사고 ]            [ 올바른 사고 ]
 "Movie 가 있어야"          "예매 시나리오:"
 "Movie.title·fee·..."      "  사용자 → Screening.reserve()"
 "Movie.getFee()"          "    Screening → Movie.calculateFee()"
 "Service 가 호출"            "      Movie → DiscountPolicy.calculate()"
                           "이 협력에 필요한 객체 + 메시지가 도출"
                           "Movie·Screening·DiscountPolicy + calculateFee/reserve"

→ 4·5장 책임 주도 설계의 핵심.

1.2 변경을 고려하라

코드의 정적 구조 = 시간이 지나며 진화. 동적 협력이 안정적 이면 정적 코드 변경 자유.

안정적 동적 협력의 특징

  • 메시지 흐름이 도메인 본질을 반영.
  • 객체 책임이 변경 이유와 일치 (SRP).
  • 협력 인터페이스가 추상 (구체 변경 자유).

→ 코드는 변해도 협력은 안정.

불안정 협력의 신호

  • 새 기능 추가 시 협력 흐름 자체가 바뀜.
  • 객체 책임이 자주 재할당.
  • 메시지 시그니처가 자주 변경.

→ 도메인 분석 부족 또는 설계 미숙 신호.


2. 도메인 모델과 구현

2.1 도메인 모델에 관하여

도메인 모델 = 비즈니스 문제 영역의 개념을 객체로 표현. 코드 이전의 사고 모델.

도메인 모델의 요소: - 도메인 객체 (Customer·Order·Product). - 객체 협력 (Order 가 Customer 에게 결제 요청). - 비즈니스 규칙 (재고 부족 시 주문 거부). - 불변식 (잔액은 음수 X).

2.2 몬스터 설계하기 — 책 사례

게임의 몬스터를 어떻게 설계할까?

잘못된 시작 — 데이터 중심

Monster: name·hp·attack·defense·image·sound
→ getter/setter 폭증
→ 행동은 외부 GameEngine
→ 빈혈 도메인

올바른 시작 — 행동 중심

1. 협력 시나리오:
   - "플레이어가 몬스터 공격 → 몬스터가 데미지 받음"
   - "몬스터가 hp 0 → 몬스터 죽음 → 아이템 드롭"
   - "몬스터가 플레이어 공격 → 플레이어가 데미지 받음"

2. 책임 식별:
   - Monster.takeDamage(amount)
   - Monster.attack(target)
   - Monster.isDead()
   - Monster.drop()   // 죽으면 아이템

3. 필요 데이터 (행동에 필요한 것만):
   - hp (takeDamage·isDead 에 필요)
   - attackPower (attack 에 필요)
   - dropTable (drop 에 필요)

→ 데이터 (필드) 가 행동의 결과로 도출.

2.3 행동과 변경을 고려한 도메인 모델

새 몬스터 종류 추가

  • 데이터 중심: Monster 의 type 필드 + switch 분기 → 산탄총 수술.
  • 책임 중심: Monster 추상 + Dragon·Goblin·Slime 자식 → 다형성, OCP.

새 행동 추가 (예: 도망)

  • 데이터 중심: 모든 Monster 자식에 flee() 추가 → 부담.
  • 책임 중심: FleeingBehavior 정책 객체 + 합성 → 새 정책 1개.

→ 변경을 견디는 도메인 모델 = 책임 주도 + 합성 + 다형성의 종합.

2.4 분석 모델·설계 모델·구현 모델

4 모델의 차이

모델 누가 만드는가 언어 도구
도메인 도메인 전문가 비즈니스 용어 인터뷰·문서
분석 모델 도메인 전문가 + 분석가 비즈니스 개념 + 관계 UML·다이어그램
설계 모델 개발자 클래스·인터페이스·협력 UML 클래스 다이어그램
구현 모델 개발자 코드 IDE

일관성의 중요성

4 모델이 같은 개념·같은 이름·같은 협력 을 공유해야: - 도메인 전문가가 "주문 (Order) 의 결제 (pay) 가 실패하면" 이라고 말함. - 분석 모델에 Order.pay() 가 있음. - 설계 모델에 Order.pay() 메서드. - 구현 모델 코드에 order.pay() 메서드.

→ 같은 이름이 4 모델 모두에 흐름 = DDD 의 Ubiquitous Language (편재 언어).

일관성 깨질 때

[ 도메인 전문가 ]     "주문이 결제되었나?"
[ 코드 ]              order.status == 2 && order.paid == true  ← 분기 의미 모름

→ 도메인 전문가가 코드 못 읽고, 개발자가 도메인 용어 못 씀. 번역 비용 폭증 + 버그 단골.

2.5 도메인 모델 표현 사례 — DDD Aggregate

// 도메인 전문가 언어 그대로
public class Order {
    private OrderId id;
    private List<OrderItem> items;
    private OrderStatus status;

    public void pay(Payment payment) {           // ← 도메인 용어
        if (status != PENDING) throw new IllegalStateException();
        // 비즈니스 규칙
        status = PAID;
        registerEvent(new OrderPaidEvent(id));
    }

    public void cancel() { ... }                  // ← 도메인 용어
    public void ship(Carrier carrier) { ... }
}

→ 도메인 전문가가 코드 (메서드 이름만이라도) 를 읽을 수 있음. DDD 의 Ubiquitous Language.


3. 책 전체의 마치며

핵심 메시지 정리 (1~15장 + 부록)

  1. 객체지향의 본질 = 객체 협력 (1·2·7·12장).
  2. 메시지가 객체를 결정 — 협력 → 책임 → 객체 (3·5·6장).
  3. 데이터 중심 X → 책임 중심 (4·5장).
  4. 추상에 의존 — OCP·DIP (8·9장).
  5. 합성 > 상속 — Stack·핸드폰 과금 (10·11장).
  6. 다형성 + LSP = 진짜 다형성 (12·13장).
  7. 일관된 협력 → 디자인 패턴 → 프레임워크 (14·15장).
  8. 계약 (사전·사후·불변) 이 LSP 의 기반 (부록 A).
  9. 타입 계층 표현 = 인터페이스 + 추상 클래스 + 합성 + sealed (부록 B).
  10. 동적 협력 먼저, 정적 코드 나중 + 4 모델 일관성 (부록 C).

다른 4권과의 연결

  • Effective Java (Bloch) — Java 매일의 권고 90개. 오브젝트 원칙의 메서드·필드 단위.
  • 리팩터링 (Fowler) — 이미 짠 코드를 오브젝트 원칙으로 개선.
  • Clean Code (Martin) — 줄·이름·함수 단위 가독성.
  • TDD (Beck) — 테스트가 오브젝트 원칙을 끌어내는 도구.

→ 5권이 자연스럽게 한 세트. → entity-object 안 5권 오각형 비교.

다음 깊이

  • Domain-Driven Design (Evans) — 도메인 모델링 + Ubiquitous Language + Aggregate.
  • Implementing Domain-Driven Design (Vernon) — DDD 실전 가이드.
  • Patterns of Enterprise Application Architecture (Fowler) — 큰 시스템 패턴.

오브젝트 가 OO 설계의 기반, DDD 가 엔터프라이즈 도메인 모델의 다음 단계.


핵심 교훈

  1. 동적 협력 먼저, 정적 코드 나중 — 코드 그리기 전에 협력 시나리오.
  2. 행동이 코드를 결정 — 데이터·필드는 행동의 결과.
  3. 변경에 강한 도메인 모델 = 책임 주도 + 합성 + 다형성.
  4. 4 모델 일관성 — 도메인·분석·설계·구현이 같은 언어 (Ubiquitous Language).
  5. 불일치는 번역 비용 + 버그 — 도메인 전문가가 코드 못 읽으면 위험 신호.

함정 / 주의

  • 코드 먼저 그리고 협력 발견 = 빈혈 도메인 모델로 직행.
  • 분석/설계/구현 모델 분리 가 도그마가 되면 문서 폭증 + 코드 동기화 비용.
  • Ubiquitous Language 도그마 — 너무 엄격하면 도메인 변화에 코드 못 따라감.
  • 거대 도메인 모델 = 모든 도메인을 한 모델에 — Bounded Context 분리 검토 (DDD).

체크리스트

  • 새 기능 설계 시 협력 시나리오 먼저 그리는가
  • 도메인 메서드 이름이 도메인 전문가 용어와 일치하는가
  • 도메인 객체가 행동을 가졌는가 (빈혈 모델 X)
  • 4 모델 (도메인·분석·설계·구현) 이 같은 언어 사용하는가
  • 큰 도메인이면 Bounded Context 분리 검토

퀴즈

  1. 동적 모델과 정적 모델 의 차이는?
  2. "행동이 코드를 결정" 의 실천적 의미?
  3. 4 모델 일관성 이 왜 중요한가?
  4. Ubiquitous Language 가 깨질 때 무엇이 어려워지는가?
  5. 오브젝트 책 전체의 한 줄 메시지를 부록 C 관점에서?

정답·해설

  1. 동적 모델 = 런타임 객체 메시지 흐름 (협력). 정적 모델 = 클래스·메서드 (코드 구조). 동적이 본질 — 객체지향의 행동 측면. 정적은 그것을 표현하는 도구.
  2. 클래스·필드부터 그리지 말고 협력 시나리오부터 그려라. 협력에 필요한 책임 → 그 책임 가진 객체 → 책임에 필요한 데이터. 데이터는 행동의 결과 (4·5장 RDD).
  3. 번역 비용 + 버그 감소. 도메인 전문가·분석가·개발자가 같은 언어를 쓰면 요구사항 → 코드 흐름이 매끄러움. 다른 언어면 매번 번역 + 오해 + 실수.
  4. 도메인 전문가가 코드 못 읽음 + 개발자가 도메인 용어 못 씀 → 매번 통역 필요, 요구사항 변경 시 어디를 어떻게 바꿀지 추적 어려움, 버그 단골.
  5. 객체지향은 정적 클래스 묶음이 아니라 동적 객체 협력이다. 그 협력이 도메인 본질을 반영하고, 4 모델이 일관 언어를 공유할 때 비로소 살아있는 도메인 모델. 책 전체가 이를 다양한 도구 (책임 주도·합성·다형성·패턴) 로 가리킴.

책 전체 완결

부록 C 가 오브젝트 의 마지막. 1~15장 + 부록 A·B·C 의 모든 통찰이 한 문장으로 모임:

객체지향의 본질은 클래스가 아니라 객체 협력이다.

이 협력을 잘하기 위한 도구 (책임 주도·추상 의존·합성·다형성·LSP·패턴·계약·일관성) 가 책 전체. 다른 4권 (Effective Java·리팩터링·Clean Code·TDD) 이 같은 원칙을 다른 단위 (메서드·1단계·줄·사이클) 로 보완.

entity-object / src-object-lecture / entity-effective-java / entity-refactoring / entity-clean-code / entity-tdd.