Chapter 1

협력하는 객체들의 공동체

  • 협력의 풍경
  • 요청과 응답으로 구성된 협력
  • 역할과 책임
  • 상태와 행동을 가진 자율적 존재
  • 메시지와 자율성
  • 객체지향의 본질

객체지향은 클래스가 아니라 협력이야. 대부분의 개발자가 객체지향을 배울 때 클래스, 상속, 캡슐화부터 시작하잖아. 저자 조영호는 그 순서가 근본적으로 잘못됐다고 보거든.

저자는 커피 주문이라는 일상적인 장면으로 시작하지. 카페에 가면 손님이 주문하고, 캐셔가 주문을 받고, 바리스타가 커피를 만들잖아. 이 세 사람은 각자의 역할을 가지고, 각자의 책임을 수행하며, 서로 요청과 응답을 주고받으면서 하나의 목표(커피를 만들어 손님에게 전달)를 달성해.

이게 바로 객체지향의 본질이라는 거지. 객체지향 시스템은 객체들이 협력하는 공동체야. 클래스 다이어그램을 그리는 게 아니라, 객체들이 어떻게 협력하는지를 설계하는 것이 먼저라는 이야기.

협력은 구체적으로 어떻게 이뤄지냐면, **요청(request)**과 **응답(response)**이야.

손님이 캐셔에게 "아메리카노 한 잔 주세요"라고 요청하지. 캐셔는 바리스타에게 "아메리카노 하나 만들어주세요"라고 다시 요청해. 바리스타가 커피를 만들어서 응답하고. 이 요청-응답의 연쇄가 협력의 실체야.

여기서 중요한 건 요청을 받은 쪽이 스스로 판단해서 응답한다는 점이지. 캐셔가 바리스타에게 "원두를 15그램 넣고 92도 물을 250ml 부어"라고 지시하지 않잖아. 그냥 "아메리카노 하나"라고 요청할 뿐이야. 어떻게 만들지는 바리스타가 알아서 결정하거든.

이 비유가 객체지향에서 왜 중요하냐면 — 객체 간의 상호작용도 이래야 한다는 거지. 하나의 객체가 다른 객체의 내부를 이리저리 건드리면서 일을 시키면 그건 협력이 아니라 통제야. 요청만 보내고, 응답을 받으면 돼.

협력이 가능하려면 참여자 각각에게 **역할(role)**이 있어야 하고, 그 역할에 따른 **책임(responsibility)**이 있어야 하지.

손님의 역할은 주문하는 것, 캐셔의 역할은 주문을 받고 전달하는 것, 바리스타의 역할은 커피를 만드는 것. 이 역할들이 겹치지 않으면서도 빈틈없이 전체 협력을 커버해.

역할의 핵심적인 특징 두 가지가 있어:

  • 대체 가능성 — 역할은 특정 사람에 묶이지 않아. 바리스타가 누구든 간에 "아메리카노를 만들 수 있다"는 역할을 수행할 수 있으면 되거든. 오늘 근무하는 바리스타가 내일 바뀌어도 카페는 돌아가지. 이게 객체지향에서 **다형성(polymorphism)**의 근원이야.
  • 다중 역할 — 한 사람이 여러 역할을 맡을 수도 있어. 작은 카페에서는 캐셔가 바리스타 역할도 겸하잖아. 객체도 마찬가지로 여러 역할을 동시에 수행할 수 있지.

저자가 여기서 강조하는 건, 객체지향 설계의 출발점은 클래스가 아니라 역할과 책임을 식별하는 것이라는 점이야. 어떤 역할이 필요하고, 그 역할이 어떤 책임을 져야 하는지를 먼저 정하고, 그다음에 그 역할을 수행할 객체를 결정하는 순서가 올바르지.

객체란 뭐냐면, **상태(state)**와 **행동(behavior)**을 가진 자율적 존재야.

바리스타를 예로 들면, 바리스타는 자신의 상태(기술 수준, 컨디션, 사용 가능한 재료 등)를 가지고 있고, 행동(커피를 만드는 것)을 수행할 수 있지. 그리고 자율적으로 판단해. 어떤 원두를 쓸지, 물 온도를 몇 도로 할지는 바리스타가 자기 상태와 판단에 따라 결정하거든.

이 "자율적"이라는 단어가 핵심이야. 객체는 수동적인 데이터 덩어리가 아니지. 스스로 판단하고 행동하는 능동적 존재야. 이게 절차지향과 객체지향의 근본적인 차이거든. 절차지향에서는 데이터가 있고 그 데이터를 처리하는 프로시저가 따로 있잖아. 객체지향에서는 데이터와 프로시저가 하나의 자율적 단위로 묶여 있지.

객체들은 어떻게 소통하냐면, **메시지(message)**를 통해서야.

앞에서 나온 "요청"이 프로그래밍 세계에서는 메시지가 되지. 한 객체가 다른 객체에게 메시지를 보내면, 받는 쪽이 그 메시지를 어떻게 처리할지 스스로 결정해. 이게 **메서드(method)**야. 메시지를 받으면 어떤 메서드를 실행할지는 수신자가 결정하는 거지.

메시지를 보내는 것메서드를 호출하는 것을 구분하는 게 중요해. 많은 개발자가 이 둘을 같은 것으로 취급하는데, 개념적으로는 달라. 메시지를 보내는 건 "무엇을 해달라"는 요청이고, 메서드는 그 요청을 "어떻게 처리할지"에 대한 수신자의 결정이거든.

이 구분이 중요한 이유는 자율성 때문이야. 메시지를 보내는 쪽은 수신자가 어떤 메서드로 처리할지 몰라. 알 필요도 없지. 그냥 "이거 해줘"라고 요청하고, 결과만 받으면 돼. 수신자의 내부 구현에 의존하지 않는 것 — 이게 캡슐화의 본질이고, 유연한 설계의 기반이야.

저자가 말하는 객체지향의 본질은 이거야:

  • 객체지향은 협력하는 객체들의 공동체를 설계하는 것이야
  • 협력은 요청과 응답의 연쇄로 이뤄지지
  • 각 객체는 역할과 책임을 가져
  • 객체는 상태와 행동을 갖춘 자율적 존재야
  • 객체 간 소통은 메시지를 통해 이뤄지며, 수신자의 자율성이 보장되어야 해

클래스, 상속, 인터페이스 같은 프로그래밍 언어 차원의 메커니즘은 이 본질을 구현하기 위한 도구일 뿐이지. 도구부터 배우면 본질을 놓치기 쉽다는 게 저자의 문제의식이고, 이 책 전체가 그 문제의식에서 출발해.


정리

1장 읽고 기억할 거 세 가지:

  1. 객체지향 = 클래스가 아니야. 객체지향의 핵심은 협력이고, 클래스는 그걸 구현하는 도구일 뿐이지
  2. 요청만 보내고 방법은 맡겨라. 객체의 자율성을 보장하는 것이 좋은 객체지향 설계의 시작이야
  3. 역할과 책임을 먼저 식별해라. 클래스를 먼저 그리지 말고, 어떤 역할이 필요하고 각 역할이 어떤 책임을 져야 하는지부터 생각해