반응형

Chapter04 역할, 책임, 협력

객체의 모양을 빚는 것은 객체가 참여하는 협력이다. 어떤 협력에 참여하는지가 객체에 필요한 행동을 결정하고, 필요한 행동이 객체의 상태를 결정한다. 개별적인 객체의 행동이나 상태가 아니라 객체들 간의 협력에 집중하라.

협력

협력은 한 사람이 다른 사람에게 도움을 요청할 때 시작된다.

요청을 했을 때 해당 요청에 응답하기 위해 새로운 요청을 보내는 등 무수한 요청과 응답을 통해 협력을 이룬다.

앨리스 이야기에 있는 재판 이야기에서 나온 재판장에서의 시나리오는 다음과 같다.

  • 왕에게 누군가가 재판을 요청한다.
  • 왕이 토끼에게 증인을 부를 것을 요청한다.
  • 왕의 요청을 받은 토끼는 모자 장수에게 증인석으로 입장할 것을 요청한다.
  • 모자 장수는 증인석에 입장함으로써 토끼의 요청에 응답한다.
  • 모자 장수의 입장은 왕이 토끼에게 요청했던 증인 호출에 대한 응답이기도 하다.
  • 이제 왕은 모자 장수에게 증언할 것을 요청한다.
  • 모자 장수는 자신이 알고 있는 내용을 증언함으로써 왕의 요청에 응답한다.

이렇게 재판이라는 일을 행하기 위해 무수히 많은 요청과 응답을 통한 협력이 이루어진다.

책임

해당 재판 시나리오에서는

  • 증언을 듣고 판결을 내려야 하는 판사
  • 증인을 데려와야 하는 토끼
  • 증언을 해야 할 모자장수

객체지향 개발에서 가장 중요한 능력은 책임을 능숙하게 소프트웨어 객체에게 할당하는 것

즉 책임을 어떻게 구현할 것인가 하는 문제는 객체와 책임이 어떻게 협력하는지 자리를 잡은 후에 고려해도 늦지 않다는 것이다.

책임의 분류

협력에 참여하는 객체들은 목표를 달성하는 데 필요한 책임을 수행한다. 책임은 객체에 의해 정의되는 응집도 있는 행위의 집합이다.

즉 객체의 책임은 ‘객체가 무엇을 알고 있는가(knowing)’와 ‘무엇을 할 수 있는가(dooing)’로 구성되는데, 크레이그 라만이 이러한 분류 체계에 따라 객체의 책임을 크게 하는 것(doing)아는 것(knowing)의 두가지 범주로 분류한다.

  • 하는 것
    • 객체를 생성하거나 계산을 하는 등의 스스로 하는 것
    • 다른 객체의 행동을 시작시키는 것
    • 다른 객체의 활동을 제어하고 조절하는 것
  • 아는 것
    • 개인적인 정보에 관해 아는 것 - 증인
    • 관련된 객체에 관해 아는 것
    • 자신이 유도하거나 계산할 수 있는 것에 관해 아는 것

책임과 메시지

위의 시나리오에서 토끼는 자기 마음대로 증인을 불러오는 것이 아닌 제어책임을 맡고 있는 왕이 토끼에게 목격자를 불러오라는 메시지를 보내야 해당 메시지에 응답하기 위해 모자 장수에게 메시지를 요청하는 것이다.

객체가 다른 객체에게 전송한 요청을 객체의 책임이 수행되도록 하는데, 이렇게 객체가 다른 객체에게 주어진 책임을 수행하도록 요청을 보내는 것을 메시지 전송이라고 한다.

메시지는 협력을 위해 한 객체가 다른 객체로 접근할 수 있는 유일한 방법이다.

이 때 책임과 메시지의 수준이 같지않다는 것을 주의해야 할 것이다.

책임은 객체가 협력에 참여하기 위해 수행해야 하는 행위를 상위 수준에서 개략적으로 서술한 것이다. 책임을 결정한 후 실제 협력을 하는 메시지를 만들 때는 하나의 책임이 여러 메시지로 분할되는 것이 일반적이다.

역할

책임의 집합이 의미하는 것

재판 시나리오에서는 왕과 모자장수를 각각 판사역할 증인역할로 나눌 수 있는데, 해당 역할을 수행하는 역할을 굳이 나누는 이유는 역할이 재사용이 가능하고 유연한 객체지향 설계를 낳는 매우 중요한 구성요소이기 때문이다.

왕과 모자 장수의 재판 이야기 이후에 나오는 시나리오를 가볍게 요약하면

  • 왕이 요리사가 증언할 것을 요청하고
  • 요리사는 요청에 응해서 증언석에 참여했다 나간다
  • 왕은 여왕에게 대신 증언을 들어달라한다
  • 이후 다음 증인으로 앨리스를 지목한다

이 시나리오를 보면 증인이라는 역할은 계속 바뀌고, 왕이 수행하던 판사 역할 또한 바뀌었다.

이렇게 역할은 다른 누군가가 대신할 수 있는 것이다.

동일한 역할로 각 책임을 이행하는데, 모자 장수와 요리사와 앨리스는 증언 방식이 다 다른데 이렇게 각 객체는 역할에 맞게 요청과 응답만 할 뿐이다.

현재 상황에서는 토끼는 바뀌지 않고 다른 사람들은 모두 바뀌니 역할을 크게 세가지로 분류할 수 있을 것이고, 각 메시지는 동일할 것이다.

  • 판사 - 목격자를 불러오라(토끼), 증언하라(증인)
  • 증인 -
  • 토끼 - 증인석에 입장하라(증인)

역할을 대체하기 위해서는..

각 역할이 수신할 수 있는 메시지를 동일한 방식으로 이해해야 한다

역할의 개념을 사용했을 때 장점

  • 유사한 협력을 추상화해서 인지 과부하를 줄일 수 있다
  • 다양한 객체들이 협력에 참여할 수 있기 때문에 협력이 좀 더 유연해지며 재사용성이 높아진다.
  • 역할은 객체지향 설계의 단순성, 유연성, 재사용성을 뒷받침하는 핵심 개념이다.

협력의 추상화

앞에서 역할을 세가지로 분류했었는데. 이렇게 객체 자체에 대해서 역할을 부여하는 것이 아닌 협력할 때의 객체에 개념을 적용해 역할 자체로 표시를 해서 흐름을 만든다면 이것이 협력의 추상화이다.

대체 가능성

이번 재판 시나리오에서는 판사와 증인이 계속 바뀌는데 이것 또한 3장에서 말했던 일반화/특수화 관계가 성립하는 것이 일반적이다.

일반화 특수화
판사 왕, 왕비
증인 모자 장수, 요리사, 앨리스

이게외연이다.

때문에 역할의 대체 가능성은 행위 호환성을 의미하고, 행위 호환성은 동일한 책임의 수행을 의미한다.

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

흔한 오류

많은 사람들은 시스템에 필요한 데이터를 저장하기 위해 객체가 존재한다는 선입견을 가지고 있다.

객체가 상태의 일부로 데이터를 포함하는 것은 사실이지만 계속 강조 했듯이 데이터는 객체가 행위를 수행하는데 필요한 재료일 뿐이고 행위를 수행하며 협력에 참여하기 위해서이다. 중요한 것은 객체의 행동, 즉 책임이다.

객체의 협력을 가장 중요시 해야한다.

예를 들어 이번 재판 시나리오에서 에 집중할 것이 아니라 왕이 어떤 협력을 이루고 있는지에 포커스를 맞춰야 하는 것이다.

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

앨리스 재판 시나리오를 생각했을 때 책임에 따른 협력 설계과정

  • 누군가는 재판을 진행해야한다.
  • 누군가는 증인을 증인석으로 불러야한다.
  • 누군가는 증언해야 한다

이렇게 협력을 구성하는 데 필요한 일련의 책임을 먼저 고안하고 나면 그 책임을 수행하는 데 필요한 객체를 선택하게 된다.

어떤 책임은 왕에게, 어떤 책임은 토끼에게 어떤 책임은 모자 장수에게 할당하면서 각 객체에 할당해나가고, 외부에 제공하게 될 행동을 정의하게 된다.

행동을 결정한 후에는 각 객체가 필요로 하는 데이터를 정의할 수 있다.

이 행동들이 모두 결정된 후에 세부사항을 구현하는 클래스를 개발할 수 있을 것이다.

범용적으로 정리하면, 객체의 행위에 초점을 맞추기 위해서는 협력이라는 실행 문맥 안에서 책임을 분배해야 한다. 각 객체가 가져야 하는 상태와 행위에 대해 고민하기 전에 그 객체가 참여할 문맥인 협력을 정의해야한다. 객체지향 시스템에서 가장 중요한 것은 충분히 자율적인 동시에 충분히 협력적인 객체를 창조하는 것이다.

객체지향 설계 기법

역할, 책임, 협력이 견고하고 유연한 객체지향 설계를 낳기위한 유용한 세가지 기법을 설명한다.

  • 책임-주도 설계(Responsibility-Driven Design)
    • 협력에 필요한 책임을 식별하고 적합한 객체에게 책임을 할당하는 방식
    • 책임에 맞게 설계를 한 이후에는 해당 책임에 대한 메시지 요청과 응답에 대한 코드를 작성하는 형식으로 짜여진 틀에 맞게 변화에 유연한 설계가 가능함
    • RDD설계하는 절차 요약
- 시스템이 사용자에게 제공해야 하는 기능인 시스템 책임을 파악한다.
- 시스템 책임을 더 작은 책임으로 분할한다.
- 분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당한다.
- 객체가 책임을 수행하는 중에 다른 객체의 도움이 필요한 경우 이를 책임질 적절한 객체 또는 역할을 찾는다.
- 해당 객체 또는 역할에게 책임을 할당함으로써 두 객체가 협력하게 한다.
  • 디자인 패턴(Design Pattern)
    • 전문가들이 반복적으로 사용하는 해결 방법을 정의해 놓은 설계 템플릿의 모음
  • 테스트-주도 개발(Test-Driven Development)
    • 테스트를 먼저 작성하고 테스트를 통과하는 구체적인 코드를 추가하면서 애플리케이션을 완성하는 방식
    • 객체가 이미 존재한다고 가정하고 어떤 메시지를 전송할 것인지에 관해 생각하고 해당 메시지에 대한 테스트를 작성하는 것이다.
    • 즉 해당 기법을 쓰기 위해서는 책임과 협력의 관점에서 객체를 바라보는 훈련이 잘 되어있어야 한다.
반응형

+ Recent posts