[Object] 3장 요약

3. 역할, 책임, 협력

객체지향 패러다임의 관점에서 핵심은 역할(role), 책임(responsibility), 협력(collaboration) 이다. 객체지향의 본질은 협력하는 객체들의 공동체를 창조하는 것이다. 객체지향 설계의 핵심은 협력을 구성하기 위해 적절한 객체를 찾고 적절한 책임을 할당하는 과정에서 드러난다.

협력

객체지향 원칙을 따르는 애플리케이션의 제어 흐름은 다양한 객체들 사이에 균형 있게 분배되는 것이 일반적이다. 객체들이 애플리케이션의 기능을 구현하기 위해 수행하는 상호작용을 협력이라고 한다. 객체가 협력에 참여하기 위해 수행하는 로직은 책임이라고 부른다. 객체들이 협력 안에서 수행하는 책임들이 모여 객체가 수행하는 역할을 구성한다.

협력

두 객체 사이의 협력은 하나의 객체가 다른 객체에게 도움을 요청할 때 시작된다. 메시지 전송(message sending) 은 객체 사이의 협력을 위해 사용할 수 있는 유일한 커뮤니케이션 수단이다. 메시지를 수신한 객체는 메서드를 실행해 요청에 응답한다. 메시지를 어떻게 처리할 지는 수신한 객체가 직접 결정한다. 이것은 객체가 자신의 일을 스스로 처리할 수 있는 자율적인 존재라는 것을 의미한다.

자율적인 객체란 자신의 상태를 직접 관리하고 스스로의 결정에 따라 행동하는 객체다. 객체를 자율적으로 만드는 가장 기본적인 방법은 내부 구현을 캡슐화하는 것이다. 자율적인 객체는 자신에게 할당된 책임을 수행하던 중에 필요한 정보를 알지 못하거나 외부의 도움이 필요한 경우 적절한 객체에게 메시지를 전송해서 협력을 요청한다.

협력이 설계를 위한 문맥을 결정한다

애플리케이션 안에 어떤 객체가 필요하다면 그 이유는 단 하나여야 한다. 객체가 협력에 참여할 수 있는 이유는 협력에 필요한 적절한 행동을 보유하고 있기 때문이다.

객체의 행동을 결정하는 것은 객체가 참여하고 있는 협력이다. 협력은 객체가 필요한 이유와 객체가 수행하는 행동의 동기를 제공한다. 객체의 행동을 결정하는 것이 협력이라면 객체의 상태를 결정하는 것은 행동이다. 객체는 자신의 상태를 스스로 결정하고 관리하는 자율적인 존재이기 때문에 객체가 수행하는 행동에 필요한 상태도 함께 가지고 있어야 한다.

객체가 참여하는 협력이 객체를 구성하는 행동과 상태 모두를 결정한다. 따라서 협력은 객체를 설계하는 데 필요한 일종의 문맥(context) 을 제공한다.

책임

책임이란 무엇인가

협력에 참여하기 위해 객체가 수행하는 행동을 책임이라고 부른다. 책임이란 객체에 의해 정의되는 응집도 있는 행위의 집합으로, 객체가 유지해야 하는 정보와 수행할 수 있는 행동에 대해 개략적으로 서술한 문장이다. 크레이그 라만(Craig Larman)은 분류 체계에 따라 객체의 책임을 크게 하는 것(doing)아는 것(knowing) 의 두 가지 범주로 나누어 세분화 하고 있다.

하는 것

  • 객체를 생성하거나 계산을 수행하는 등의 스스로 하는 것
  • 다른 객체의 행동을 시작시키는 것
  • 다른 객체의 활동을 제어하고 조절하는 것

아는 것

  • 사적인 정보에 관해 아는 것
  • 관련된 객체에 관해 아는 것
  • 자신이 유도하거나 계산할 수 있는 것에 관해 아는 것


책임과 메시지의 크기는 다르다. 책임은 객체가 수행할 수 있는 행동을 종합적이고 간략하게 서술하기 때문에 메시지보다 추상적이고 개념적으로도 더 크다. 중요한 사실은 책임의 관점에서 ‘아는 것’과 ‘하는 것’이 밀접하게 연관돼 있다는 점이다. 객체는 자신이 맡은 책임을 수행하는 데 필요한 정보를 알고 있을 책임이 있다.

책임은 객체지향 설계의 핵심이다. 크레이그 라만은 "객체지향 개발에서 가장 중요한 능력은 책임을 능숙하게 소프트웨어 객체에 할당하는 것이라는 말로 책임 할당의 중요성을 강조하기도 했다. 협력이 중요한 이유는 객체에게 할당할 책임을 결정할 수 있는 문맥을 제공하기 때문이다. 적절한 협력적절한 책임을 제공하고, 적절한 책임적절한 객체에게 할당해야만 단순하고 유연한 설계를 창조할 수 있다.

책임 할당

자율적인 객체를 만드는 가장 기본적인 방법은 책임을 수행하는 데 필요한 정보를 가장 잘 알고 있는 전문가에게 그 책임을 할당하는 것이다. 이를 책임 할당을 위한 INFORMATION EXPERT(정보 전문가) 패턴이라고 부른다.

객체에게 책임을 할당하기 위해서는 먼저 협력이라는 문맥을 정의해야 한다. 협력을 설계하는 출발점은 시스템이 사용자에게 제공하는 기능을 시스템이 담당할 하나의 책임으로 바라보는 것이다. 책임을 완료하는 데 필요한 더 작은 책임을 찾아내고 이를 객체들에게 할당하는 반복적인 과정을 통해 모양을 갖춰간다.

협력을 설계하면서 객체의 책임을 식별해 나가는 과정에서 최종적으로 얻게 되는 결과물은 시스템을 구성하는 객체들의 인터페이스와 오퍼레이션의 목록이다.

책임 주도 설계

책임을 찾고 책임을 수행할 적절한 객체를 찾아 책임을 할당하는 방식으로 협력을 설계하는 방법을 책임 주도 설계(Responsibility-Driven Design, RDD) 라고 부른다. 책임 주도 설계는 자연스럽게 객체의 구현이 아닌 책임에 집중할 수 있게 한다. 책임을 할당할 때 고려해야 하는 두 가지 요소로 메시지가 객체를 결정한다는 것과 행동이 상태를 결정한다는 것이다.

메시지가 객체를 결정한다

메시지가 객체를 선택하게 해야 하는 두 가지 중요한 이유가 있다.

  1. 객체가 최소한의 인터페이스(minimal interface) 를 가질 수 있게 된다.
  2. 객체는 충분히 추상적인 인터페이스(abstract interface) 를 가질 수 있게 된다. 메시지를 먼저 식별하면 무엇을 수행할지에 초점을 맞추는 인터페이스를 얻을 수 있다.


행동이 상태를 결정한다

객체를 객체답게 만드는 것은 객체의 상태가 아니라 객체가 다른 객체에게 제공하는 행동이다. 객체의 행동은 객체가 협력에 참여할 수 있는 유일한 방법이다.

객체의 행동이 아니라 상태에 초점을 맞출 경우 내부 구현이 객체의 퍼블릭 인터페이스에 노출되도록 만들기 때문에 캡슐화를 저해한다. 레바카 워프스브록은 이와 같이 객체의 내부 구현에 초점을 맞춘 설계 방법을 데이터-주도 설계(Data-Driven Design) 이라고 부르기도 했다.

캡슐화를 위반하지 않도록 항상 협력이라는 문맥 안에서 객체를 생각해야 한다. 협력 관계 속에서 다른 객체에게 무엇을 제공해야 하고 다른 객체로부터 무엇을 얻어야 하는지를 고민해야만 훌륭한 책임을 수확할 수 있다. 시스템의 기능을 구현하기 위한 협력에 초점을 맞춰야만 응집도가 높고 결합도가 낮은 객체들을 창조할 수 있다.

역할

객체가 어떤 특정한 협력 안에서 수행하는 책임의 집합을 역할이라고 부른다.

유연하고 재사용 가능한 협력

역할이 중요한 이유는 역할을 통해 유연하고 재사용 가능한 협력을 얻을 수 있기 때문이다.

역할은 다른 것으로 교체할 수 있는 책임의 집합이다.

책임과 역할을 중심으로 협력을 바라보는 것이 바로 변경과 확장이 용이한 유연한 설계로 나아가는 첫걸음이다.

객체 대 역할

협력에 참여하는 후보가 여러 종류의 객체에 의해 수행될 필요가 있다면 그 후보는 역할이 되지만 단지 한 종류의 객체만이 협력에 참여할 필요가 있다면 후보는 객체가 된다. 다시 말해 협력에 적합한 책임을 수행하는 대상이 한 종류라면 간단하게 객체로 간주한다. 트리그비 린스카우(Trygve Reesnkaug)는 역할을 가리켜 실행되는 동안 협력 안에서 각자의 위치를 가지는 객체들에 대한 별칭이라고 정의하기도 한다.

설계 초반에는 적절한 책임과 협력의 큰 그림을 탐색하는 것이 가장 중요한 목표여야 하고 역할과 객체를 명확하게 구분하는 것은 그렇게 중요하지는 않다는 것이다. 다양한 객체들이 협력에 참여한다는 것이 확실하다면 역할로 시작하라. 정확한 결정을 내리기 어려운 상황이라면 구체적인 객체로 시작하라. 협력을 구체적인 객체가 아니라 추상적인 역할의 관점에서 설계하면 협력이 유연하고 재사용 가능해진다는 것이다.

역할과 추상화

추상화의 첫 번째 장점은 세부사항에 억눌리지 않고도 상위 수준의 정책을 쉽고 간단하게 표현할 수 있다는 것이다. 추상화를 적절하게 사용하면 불필요한 세부 사항을 생략하고 핵심적인 개념을 강조할 수 있다. 협력이라는 관점에서는 세부적인 사항을 무시하고 추상화에 집중하는 것이 유용하다. 추상화의 두 번째 장점은 설계를 유연하게 만들 수 있다는 것이다.

배우와 배역

연극 안에서 배역을 연기하는 배우라는 은유는 협력 안에서 역할을 수행하는 객체라는 관점이 가진 입체적인 측면을 훌륭하게 담아낸다. 협력은 연극과 동일하고 코드는 극본과 동일하다. 협력이라는 문맥 안에서 역할은 특정 협력에 참여해서 책임을 수행하는 객체의 일부다.

객체는 여러 역할을 가질 수 있지만 특정한 협력 안에서는 일시적으로 오직 하나의 역할만이 보여진다. 역할은 특정한 객체의 종류를 캡슐화하기 때문에 동일한 역할을 수행하고 계약을 준수하는 대체 가능한 객체들은 다형적이다.

Leave a comment