시너지를 생각하라. 전체는 부분의 합보다 크다.
객체지향이라고 불리는 새로운 세상의 문을 연 대부분의 사람들은 "객체지향이란 실세계를 직접적이고 직관적으로 모델링할 수 있는 패러다임"이라는 설명과 마주게 된다.
객체지향 소프트웨어는 실세계의 투영이며, 객체란 현실 세계에 존재하는 사물에 대한 추상화라는 것이다.
객체지향에서 가장 중요한 개념 세 가지는 바로 역할, 책임, 협력이다.
요청과 응답으로 구성된 협력
일상에서 발생하는 대부분의 문제는 개인 혼자만의 힘으로 해결하기 버거울 정도로 복잡하기 때문에 사람들은 혼자서 문제를 해결하기보다는 다른 사람들의 도움을 받아 문제를 해결하는 것을 선호한다.
사람들은 해결에 필요한 지식을 알고 있거나 서비스를 제공해줄 수 있는 사람에게 도움을 요청한다.
요청을 받은 사람은 주어진 책임을 다하면서 필요한 지식이나 서비스를 제공한다. 다른 사람의 요청에 응답한다.
역할과 책임
사람들은 다른 사람과 협력하는 과정 속에서 특정한 역할을 부여받는다. 카페테리아에서 손님이 주문한 커피를 제조하기 위해 캐시어와 바리스타가 협력하는 과정 속에는 손님, 캐시어, 바리스타 라는 역할이 존재한다.
역할은 어떤 협력에 참여하는 특정한 사람이 협력 안에서 차지하는 책임이나 임무를 의미한다. 어떤 사람이 손님이라는 역할을 맡았다면 그 사람은 커피를 주문하는 임무를 맡게 된다.
역할이라는 단어에는 의미적으로 책임이라는 개념을 내포한다. 특정한 역할은 특정한 책임을 암시한다. 협력에 참여하며 특정한 역할을 수행하는 사람들은 역할에 적합한 책임을 수행하게 된다.
사람들은 협력을 위해 특정한 역할에 적합한 책임을 수행한다는 사실은 몇가지 중요한 개념을 제시한다.
기능을 구현하기 위해 협력하는 객체들
사람이라는 단어를 객체로, 에이전트의 요청을 메시지로, 에이전트가 요청을 처리하는 방법을 메서드로 바꾸면 마법처럼 대부분의 설명을 객체지향이라는 문맥으로 옮겨올 수 있다. 이것이 바로 많은 사람들이 객체지향을 설명하기 위해 실세계의 모방이라는 은유를 차용하는 이유이다.
역할과 책임을 수행하며 협력하는 객체들
협력의 핵심은 특정한 책임을 수행하는 역할들 간의 연쇄적인 요청과 응답을 통해 목표를 달성한다는 것이다. 일상생활에서 목표는 사람들의 협력을 통해 달성되며, 목표는 더 작은 책임으로 분할되고 책임을 수행할 수 있는 적절한 역할을 가진 사람에 의해 수행된다.
객체의 역할은 사람의 역할과 유사하게 다음과 같은 특징을 가진다.
역할과 책임은 객체지향 패러다임의 중요한 기반을 제공하는 다형성과도 깊이 연관돼있다.
객체지향 애플리케이션의 운곽을 결정하는 것은 역할, 책임, 협력이지만 실제로 협력에 참여하는 주체는 객체다. 만약 실행 중인 애플리케이션의 내부를 눈으로 직접 볼 수 있다면 그 안에는 쉴 새 없이 메시지를 주고받으며 협력하는 객체가 존재한다는 것을 확인할 수 있을 것이다.
객체는 애플리케이션의 기능을 구현하기 위해 존재한다. 아주 작은 기능조차 객체 혼자 감당하기에는 버거울 정도로 복잡하고 거대하기 때문에 일반적으로 객체는 다른 객체와의 협력을 통해 기능을 구현하게 된다.
협력 공동체의 일원으로서 객체는 다음과 같은 두 가지 덕목을 갖춰야 하며, 두 덕목 사이에서 균형을 유지해야 한다.
첫째, 객체는 충분히 협력적이어야 한다. 다른 객체의 요청에 충실히 귀 기울이고 다른 객체에게 적극적으로 도움을 요청할 정도로 열린 마음을 지녀야 한다. 외부의 도움을 무시한 채 모든 것을 스스로 처리하려고 하는 전지전능한 객체는 내부적인 복잡도에 의해 자멸하고 만다.
두번째 덕목으로는 객체가 충분히 자율적이어야 한다. 자율적이라는 단어의 뜻은 자기 스스로의 원칙에 따라 어떤 일을 하거나 자기 스스로를 통제하여 절제하는 것을 의미한다. 어떤 사물이 자신의 행동을 스스로 결정하고 책임진다면 우리는 그 사물을 자율적인 존재라고 말한다.
상태와 행동을 함께 지닌 자율적인 객체
흔히 객체를 상태와 행동을 함께 지닌 실체라고 정의한다. 이 말은 객체가 협력에 참여하기 위해 어떤 행동을 해야 한다면 그 행동을 하는 데 필요한 상태도 함께 지니고 있어야 한다는 것을 의미한다.
협력과 메세지
객체지향의 세계에세는 오직 한 가지 의사소통 수단만이 존재한다. 이를 메시지라고 한다. 한 객체가 다른 객체에게 요청하는 것을 메시지를 전송한다고 말하고 다른 객체로부터 요청을 받는 것을 메시지를 수신한다고 말한다. 이때 메시지를 전송하는 객체를 송신자 수신하는 객체를 수신자라고 부른다
메서드와 자율성
수신자는 먼저 수신된 메시지를 이해할 수 있는지 여부를 판단한 후 미리 정해진 자신만의 방법에 따라 메시지를 처리한다. 이처럼 객체가 수신된 메시지를 처리하는 방법을 메서드라고 부른다.
외부의 요청이 무엇인지를 표현하는 메시지와 요청을 처리하기 위한 구체적인 방법인 메서드를 분리하는 것은 객체의 자율성을 높이는 핵심 메커니즘이다. 이것은 캡슐화라는 개념과도 깊이 관련돼 있다.
객체를 지향하라
객체지향의 세계에서 클래스는 에스키모인들의 눈과 유사하다. 에스키모인들이 눈을 표현할 때 400가지 이상의 표현법이 존재한다고한다. 하지만 실제 에스키모인들이 사용하는 표현은 4가지라고 한다.
이처럼 객체지향 언어에서 프로그래밍 언어라는 다리를 건너면서 조금씩 부풀려졌다. 그 결과 사람들은 객체지향의 중심에 있어야 할 객체로부터 조금씩 멀어져 갔다.
1장 결론: 클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하라. 객체지향은 객체를 지향하는 것이지 클래스를 지향하는 것이 아니다.
객체지향 패러다임은 지식을 추상화하고 추상화한 지식을 객체 안에 캡슐화함으로써 실세계 문제에 내재된 복잡성을 관리하려고 한다. 객체를 발견하고 창조하는 것은 지식과 행동을 구조화하는 문제다. -레베카 워프스브록-
인간은 본능적으로 세상을 독립적이고 식별 가능한 객체의 집합으로 바라본다. 많은 사람들이 객체지향을 직관적이고 이해하기 쉬운 패러다임이라고 말하는 이유는 객체지향이 세상을 자율적이고 독립적인 객체들로 분해할 수 있는 인간의 기본적인 인지 능력에 기반을 두고 있기 때문이다.
객체지향 패러다임은 인간이 인지할 수 있는 다양한 객체들이 모여 현실 세계를 이루는 것처럼 소프트웨어의 세계 역시 인간이 인지할 수 있는 다양한 소프트웨어 객체들이 모여 이뤄져 있다는 믿음에서 출발한다. 그러나 목적은 현실 세계를 모방하는 것이 아니라 현실 세계를 기반으로 새로운 세계를 창조하는 것이다.
앨리스 객체
앨리스는 작은 문을 통과하기 위해 자신의 상태를 변화 시켰다. 문을 통과하기 위한 앨리스의 상태를 적당한 키라고 표현한다. 앨리스의 상태는 앨리스의 행동에 따라 변화한다. 앨리스가 문을 통과하기 위해 상태를 맞추려면 행동이 필요하다. 행동으로 문에 맞는 상태를 맞춰야하기 때문이다.
객체의 다양한 특성을 효과적으로 설명하기 위해서는 객체를 상태, 행동, 식별자를 지닌 실체로 보는 것이 가장 효과적이다.
이 책에서는 다음과 같이 정의한다.
객체란 식별 가능한 개체 또는 사물이다. 객체는 자동차처럼 만질 수 있는 구체적인 사물일 수도 있고, 시간처럼 추상적인 개념일 수도 있다. 객체는 구별 가능한 식별자, 특징적인 행동, 변경 가능한 상태를 가진다. 소프트웨어 안에서 객체는 저장된 상태와 실행 가능한 코드를 통해 구현된다.
상태
객체가 주변 환경과의 상호작용에 어떻게 반응하는가는 그 시점까지 객체에 어떤 일이 발생했느냐에 좌우된다. 모든 일들의 공통점은 어떤 행동의 결과는 과거에 어떤 행동들이 일어났었느냐에 의존한다는 것이다.
상태와 프로퍼티
모든 객체의 상태는 단순한 값과 객체의 조합으로 표현할 수 있다. 이때 객체의 상태를 구성하는 모든 특징을 통틀어 객체의 프로퍼티라고 한다. 앨리스의 경우 키, 위치, 음료가 앨리스의 프로퍼티가 된다. 일반적인 프로터피는 변경되지 않고 고정되기 때문에 정적이다. 반면 프로퍼티 값은 시간이 흐름에 따라 변경되기 때문에 동적이다.
이 책에서는 객체의 상태를 다음과 같이 정의하기로 한다.
상태는 특정 시점에 객체가 가지고 있는 정보의 집합으로 객체의 구조적 특징을 표현한다. 객체의 상태는 객체에 존재하는 정적인 프로퍼티와 동적인 프로퍼티 값으로 구성된다. 객체의 프로퍼티는 단순한 값과 다른 객체를 참조하는 링크로 구분할 수 있다.
객체는 자율적인 존재라는 점을 명시하라. 객체지향의 세계에서 객체는 다른 객체의 상태에 직접적으로 접근할 수도, 상태를 변경할 수도 없다. 자율적인 객체는 스스로 자신의 상태를 책임져야 한다.
행동
상태와 행동
객체의 상태는 저절로 변경되지 않는다. 객체의 상태를 변경하는 것은 객체의 자발적인 행동뿐이다. 객체가 취하는 행동은 객체 자신의 상태를 변경시킨다. 객체의 행동에 의해 객체의 상태가 변경된다는 것은 행동이 부수 효과를 초래한다는 것을 의미한다. 부수 효과의 개념을 이용하면 객체의 행동을 상태 변경의 관점에서 쉽게 기술할 수 있다.
상태와 행동 사이에는 다음과 같은 관계가 있다.
협력과 행동
객체의 행동으로 인해 발생하는 결과는 두 가지 관점에서 설명할 수 있다. 객체의 행동은 이 두 가지 관점의 부수효과를 명확하게 서술해야 한다.
이 책에서는 행동을 다음과 같이 정의한다.
행동이란 외부의 요청 또는 수신된 메시지에 응답하기 위해 동작하고 반응하는 활동이다. 행동의 결과로 객체는 자신의 상태를 변경하거나 다른 객체에게 메시지를 전달할 수 있다. 객체는 행동을 통해 다른 객체와의 협력에 참여하므로 행동은 외부에 가시적이어야 한다.
상태 캡슐화
상태를 잘 정의된 행동 집합 뒤로 캡슐화하는 것은 객체의 자율성을 높이고 협력을 단순하고 유연하게 만든다. 이것이 상태를 캡슐화해야 하는 이유이다.
식별자
객체란 인간의 인지 능력을 이용해 식별 가능한 경계를 가진 모든 사물을 의미한다. 객체가 식별 가능하다는 것은 객체를 서로 구별할 수 있는 특정한 프로퍼티가 객체 안에 존재한다는 것을 의미한다. 이 프로퍼티를 식별자라고 한다. 모든 객체는 식별자를 가지며 식별자를 이용해 객체를 구별할 수 있다.
값은 숫자, 문자열, 날짜, 시간, 금액 등과 같이 변하지 않는 양을 모델링한다. 흔히 값의 상태는 변하지 않기 때문에 불변 상태를 가진다고 말한다.
p 57 부터 이어서