티스토리 뷰

4. 역할, 책임, 협력

우리 모두를 합친 것보다 더 현명한 사람은 없다.
중요한 것은 개별 객체가 아니라 객체들 사이에 이뤄지는 협력이다.

  • 훌륭한 객체지향 설계자는 객체들 간의 요청과 응답속에서 창발하는 협력에 초점을 맞춰 애플리케이션을 설계한다.
  • 협력이 자리를 잡으면 저절로 객체 행동이 드러나고 뒤이어 적절한 상태가 결정된다.

협력

  • 협력은 한사람이 다른 사람에게 도움을 요청할 때 시작된다.
  • 자신에게 할당된 일이나 업무를 처리하던 중에 스스로 해결하기 어려운 문제에 부딪히게 되면 문제를 해결하는데 필요한 지식을 알고 있거나 도움을 받을 수 있는 누군가에게 도움을 요청하게 된다.
  • 요청을 받은 사람은 일을 처리한 후 요청한 사람에게 필요한 지식이나 서비스를 제공하는 것으로 요청에 응답한다.
  • 결과적으로 협력은 다수의 요청과 응답을 구성되며 전체적으로 협력은 다수의 연쇄적인 요청과 응답의 흐름으로 구성된다.

재판 속의 협력

  • 앨리스의 이야기에서 왕이 모자 장수로부터 증언을 듣는 과정을 요청과 응답이라는 관점에서 살펴보자.
    • 누군가 왕에게 재판을 요청함으로써 재판이 시작된다.
    • 왕이 하얀 토끼에게 증인을 부를 것을 요청한다.
    • 왕의 요청을 받은 토끼는 모자 장수에게 증인석으로 입장할 것을 요청한다.
    • 모자 장수는 증인석에 입장함으로써 토끼의 요청에 응답한다.
    • 모자 장수의 입장은 왕이 토끼에게 요청했던 증인 호출에 대한 응답이기도 하다.
    • 이제 왕은 모자 장수에게 증언할 것을 요청한다.
    • 모자 장수는 자신이 알고있는 내용을 증언함으로써 왕의 요청에 응답한다.

책임

  • 객체지향의 세계에서는 어떤 객체가 어떤 요청에 대해 대답해 줄 수 있거나, 적절한 행동을 할 의무가 있는 경우 해당 객체가 책임을 가진다고 말한다.
    • 왕은 '재판을 수행하라'는 요청에 응답해야 하므로 '재판을 수행할'책임을 지게 된다.
    • 하얀 토끼의 경우에는 '목격자를 불러오라'는 요청에 적절히 응답해야 하므로 '목격자를 불러올'책임을 진다.
    • 모자 장수는 '증인석에 입장'하고 '증언할' 책임을 지게 된다.
  • 어떤 대상에 대한 요청은 그 대상이 요청을 처리할 책임이 있음을 암시한다.
  • 책임을 어떻게 구현할 것인가 하는 문제는 객체와 책임이 제자리를 잡은 후에 고려해도 늦지 않다.
  • 객체와 책임이 이리저리 부유하는 상황에서 성급하게 구현에 뛰어든 넋은 변경에 취약하고 다양한 협력에 참여할 수 없는 비자율적인 객체를 낳게 된다.

책임의 분류

  • 객체의 책임은 '객체가 무엇을 알고 있는가(knowing)'와 '무엇을 할 수 있는가(doing)'로 구성된다.
    • 하는것(doing)
      • 객체를 생성하거나 계산을 하는 등의 스스로 하는 것
      • 다른 객체의 행동을 시작시키는 것
      • 다른 객체의 활동을 제어하고 조절하는 것
    • 아는 것(knowing)
      • 개인적인 정보에 관해 아는 것
      • 관련된 객체에 관해 아는 것
      • 자신이 유도하거나 계산할 수 있는 것에 관해 아는 것
  • 엘리스 이야기에서...
    • 왕은 재판 집행이라는 책임을 수행하기 위해 먼저 하얀 토끼에게 목격자를 불러오도록 요청한 후 모격자인 모자 장수에게 증언을 하라고 요청한다.
      • 왕은 재판에 참여하는 "다른 객체들의 활동을 제어하고 조율"하고 있다. 따라서 왕은 하는 것과 관련된 책임을 수행하고 있다.
    • 하얀 토끼는 목격자가 모자 장수라는 사실을 알고 있으며, 동시에 모자장수가 증인석에 입장하도록 요청한다.
      • 첫번째 책임은 "관련된 객체에 대해 아는 것"에 해당하고
      • 두번째 책임은 "다른 객체의 행동을 시작시키는 것"에 해당한다.
      • 하얀 토끼는 아는 것하는 것의 두 가지 종류의 책임을 모두 수행하고 있다.
    • 모자 장수의 경우 스스로 증인석에 입장해야 하는 책임과 자신이 알고 있는 사실을 증언해야 할 책임을 가지고 있다.
      • "객체를 생성하거나 계산을 하는 등의 스스로 하는 것"에 대한 책임
      • "자신이 유도하거나 계산할 수 있는 것에 관해 아는 것"에 대한 책임
      • 모자 장수 역시 재판이라는 협력 안에서 아는 것과 하는 것의 두가지 종류의 책임을 모두 수행하고 있다.
  • 객체의 책임을 이야기할 때는 일반적으로 외부에서 접근 가능한 공용 서비스의 관점에서 이야기한다.
  • 즉, 책임객체의 외부에 제공해 줄 수 있는 정보(아는 것의 측면)와 외부에 제공해 줄수 있는 서비스(하는 것의 측면)의 목록이다.
  • 책임은 객체의 공용 인터페이스를 구성한다.

공용 인터페이스
객체지향의 중요한 원리 중 하나인 캡슐화로 이어진다.

책임과 메시지

  • 객체가 다른 객체에게 주어진 책임을 수행하도록 요청을 보내는 것을 메시지 전송(message-send)이라고 한다.
  • 두 객체간의 협력은 메시지를 통해 이뤄진다.
  • 메시지는 협력을 위해 한 객체가 다른 객체로 접근할 수 있는 유일한 방법이다.
  • 책임과 메시지의 수준이 같지는 않다.
  • 책임은 객체가 렵력에 참여하기 위해 수행해야하는 행위를 상위 수준에서 개략적으로 서술한 것이다.
  • 책임을 결정한 후 실제로 협력을 정제하면서 이를 메시지로 변환할 때는 하나의 책임이 여러 메시지로 분할되는 것이 일반적이다.
  • 설계를 시작한는 초반에는 어떤 객체가 어떤 책임을 가지고 어떤방시으로 서로 협력해야 하는지에 대한 개요를 아는 것만으로도 충분하다.
  • 어떤 클래스가 필요하고 어떤 메서드를 조합해야 하는지를 결정하는 것은 책임과 메시지에 대한 대략적인 윤곽을 잡은 후에 시작해도 늦지 않다.

역할

책임의 집합이 의미하는 것

  • 역할은 책임의 집합이다.
  • 재판이라는 협력에 참여하기 위해 모자 장수는 '증인'이라는 역할을 수행한다.
  • 왕은 '판사'라는 역할을 수행하고 있다.
  • 역할이 재사용 가능하고 유연한 객체지향 설계를 낳는 매우 중요한 구성요소다.

역할이 답이다.

  • 문제는 협력에 참여하는 등장인물들을 제외한 나머지 과정이 너무나도 유사해서 하나의 협력으로 다루고 싶다는 것이다.
  • '판사'와 '증인'이라는 역할을 사용하면 세 가지 협력을 모두 포괄할 수 있는 하나의 협력으로 추상화 할 수 있다.
    • 재판이라는 협력 과정 속에서 하트왕과 하트 여왕은 '판사'의 역할을 수행한다.
    • 모자 장수와 요리사, 엘리스는 '증인'의 역할을 수행한다.
  • 협력 안에서 역할은 "이 자리는 해당 역할을 수행할 수 있는 어떤 객체라도 대신할 수 있습니다"라고 말하는 것과 같다.
  • 역할의 개념을 사용하면 유사한 협력을 추상화해서 인지 과부하를 줄일 수 있다.
  • 다양한 객체들이 협력에 참여할 수 있기 때문에 협력이 좀 더 유연해지며 다양한 객체들이 동일한 협력에 참여할 수 잇기 때문에 재사용성이 높아진다.
  • 역할은 객체지향 설계의 단순성(Simplicity), 유연성(flexibility), 재사용성(reusability)을 뒷받침하는 핵심 개념이다.

협력의 추상화

  • 역할의 가장 큰 가치는 하나의 협력안에 여러 종류의 객체가 참여할 수 있게 함으로써 협력을 추상화할 수 있다는 것이다.
  • 협력의 추상화는 설계자가 다뤄야 하는 협력의 개수를 줄이는 동시에 구체적인 객체를 추상적인 역할로 대체함으로써 협력의 양상을 단순화한다.
  • 객체로 추상적인 역할을 대체해서 동일한 구조의 협력을 다양한 문맥에서 재사용할 수 있는 능력은 과거의 전통적인 패러다임과 구분되는 객체지향만의 힘이다.
  • 그 힘은 근본적으로 역할의 대체 가능성에서 비롯된다.

대체 가능성

  • 역할은 다른 객체에 의해 대체 가능함을 의미한다.
  • 객체가 역할을 대체하기 위해서는 행동이 호환돼야 한다.
  • 객체가 역할을 대체 가능하기 위해서는 협력 안에서 역할이 수행하는 모든 책임을 동일하게 수행할 수 있어야 한다.
  • 객체는 역할이 암시하는 책임보다 더 많은 책임을 가질 수 있다.
  • 대부분의 경우에 객체의 타입과 역할 사이에는 일반화/특수화 관계가 성립하는 것이 일반적이다.
  • 역할이 협력을 추상적으로 만들 수 있는 이유는 역할 자체가 객체의 추상화이기 때문이다.
  • 역할의 대체 가능성은 행위 호환성을 의미하고, 행위 호환성은 동일한 책임의 수행을 의미한다.

객체의 모양을 결정하는 협력

흔한 오류

  • 많은 사람들은 시스템에 필요한 데이터를 저장하기 위해 객체가 존재한다는 선입견을 가지고 있다.
    • 객체가 상태의일부로 데이터를 포함하는 것은 사실이지만 데이터는 단지 객체가 행위를 수행하는데 필요한 재료일 뿐이다.
    • 객체가 존재하는 이유는 행위를 수행하며 협력에 참여하기 위해서다.
  • 객체지향이 클래스와 클래스 간의 관계를 표현하는 시스템의 정적인 측면에 중점을 둔다는 것이다.
    • 중요한 것은 클래스가 아니라 협력에 참여하는 동적인 객체이며,
    • 클래스는 단지 시스템에 필요한 객체를 표현하고 생성하기 위해 프로그래밍 언어가 제공하는 구현 메커니즘이라는 사실을 기억하라.
    • 객체지향의 핵심은 클래스를 어떻게 구현할 것인가각 아니라 객체가 협력안에서 어떤 책임과 역할을 수행할 것인지를 결정하는 것이다.
  • 객체지향 입문자들이 데이터나 클래스를 중심으로 애플리케이션을 설계하는 이유는 협력이라는 문맥을 고려하지 않고 각 객체를 독립적으로 바라보기 때문이다.
  • 처음에는 전형적인왕의 모습을 빌려 소프트웨어 객체를 창조하는 것이 합리적이고 적절해 보일지 모르지만...
  • 실제로 동작하는 애플리케이션을 구축하기 위해서는 왕이 참여하는 협력을 우선적으로 고려해야 한다.

협력을 따라 흐르는 객체의 책임

  • 올바른 객체를 설계하기 위해서는 먼저 견고하고 깔끔한 협력을 설계해야 한다.
  • 협력을 설계한다는 것은 설계에 참여하는 객체들이 주고받을 요청과 응답의 흐름을 결정한다는 것을 의미한다.
  • 이렇게 결정된 요청과 응답의 흐름객체가 협력에 참여하기 위해 수행될 책임이 된다.
  • 객체에게 책임을 할당하고 나면 책임은 객체가 외부에 제공하게될 행동이 된다.
  • 협력이라는 문맥에서 객체가 수행하게 될 적절한 책임, 즉 행동을 결정한 후에 그 행동을 수행한느데 필요한 데이터를 고민해야 한다.
  • 객체가 협력에 참여하기 위해 필요한 데이터와 행동이 어느정도 결정된 후에 클래스의 구현방법을 결정해야 한다.
  • 클래스와 데이터는 협력과 책임의 집합이 결정된 후에야 무대 위에 등장할 수 있다.
  • 객체지향 시스템에서 가장 중요한 것은 충분히 자율적인 동시에 충분히 협력적인 객체를 창조하는 것이다.
  • 객체를 충분히 협력적으로 만든 후에 협력이라는 문맥 안에서 객체를 충분히 자율적으로 만드는 것이다.

객체지향 설계 기법

  1. 책임 주도 설계
  2. 디자인 패턴
  3. 테스트 주도 개발
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함