[OOP : 오브젝트] 3. 역할, 책임, 협력

KIM KYUBIN·2022년 10월 3일
0

OOP

목록 보기
7/7

오브젝트 : 코드로 이해하는 객체지향 설계 - 조영호 저

1. 협력

  • 객체지향 원칙을 따르는 애플리케이션의 제어 흐름은 어떤 하나의 객체에 의해 통제되지 않고 다양한 객체들 사이에 균형 있게 분배되는 것이 일반적이다.

  • 협력 : 객체들이 애플리케이션의 기능을 구현하기 위해 수행하는 상호작용

  • 책임 : 객체가 협력에 참여하기 위해 수행하는 로직

  • 객체들이 협력 안에서 수행하는 책임들이 모여 객체가 수행하는 역할을 구성한다.

1.1 협력

  • 메시지 전송(message sending) : 객체 사이의 협력을 위해 사용할 수 있는 유일한 커뮤니케이션 수단

  • 메시지를 수신한 객체는 메서드를 실행해 요청에 응답한다.

    • 외부의 객체는 오직 메시지만 전송할 수 있을 뿐이며 메시지를 어떻게 처리할지는 메시지를 수신한 객체가 직접 결정한다.
  • 자신이 할 수 없는 일을 다른 객체에게 위임하면 협력에 참여하는 객체들의 전체적인 자율성을 향상시킬 수 있다.

  • 객체를 자율적으로 만드는 가장 기본적인 방법은 내부 구현을 캡슐화하는 것이다.

  • 객체들 사이의 협력을 구성하는 일련의 요청과 응답의 흐름을 통해 애플리케이션의 기능이 구현된다.

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

  • 객체의 행동을 결정하는 것이 협력이라면 객체의 상태를 결정하는 것은 행동이다.

  • 객체의 상태는 그 객체가 행동을 수행하는 데 필요한 정보가 무엇인지로 결정된다.

  • 객체가 참여하는 협력이 객체를 구성하는 행동과 상태 모두를 결정한다.

    • 협력은 객체를 설계하는 데 필요한 일종의 문맥(context)을 제공한다.

2. 책임

2.1 책임이란 무엇인가?

  • 객체를 설계하기 위해 필요한 문맥인 협력이 갖춰졌으면 다음으로 할 일은 협력에 필요한 행동을 수행할 수 있는 적절한 객체를 찾는 것이다.
    => 이때, 협력에 참여하기 위해 객체가 수행하는 행동을 책임이라고 부른다.
  • 책임이란 객체에 의해 정의되는 응집도 있는 행위의 집합으로, 객체가 유지해야 하는 정보와 수행할 수 있는 행동에 대해 개략적으로 서술한 문장이다.
    => 즉, 객체의 책임은 객체가 '무엇을 알고 있는가'(knowing)와 '무엇을 할 수 있는가'(doing)로 구성된다.
  • 협력 안에서 객체에게 할당한 책임이 외부의 인터페이스와 내부의 속성을 결정한다.
  • 일반적으로 책임과 메시지의 크기는 다르다.
    => 책임은 객체가 수행할 수 있는 행동을 종합적이고 간략하게 서술하기 때문에 메시지보다 추상적이고 개념적으로도 더 크다.
  • 중요한 사실은 책임의 관점에서 '아는 것'과 '하는 것'이 밀접하게 연관돼 있다는 점이다.
    => 객체는 자신이 맡은 책임을 수행하는 데 필요한 정보를 알고 있을 책임이 있다.
    => 객체는 자신이 할 수 없는 작업을 도와줄 객체를 알고 있을 책임이 있다.
    => 어떤 책임을 수행하기 위해서는 그 책임을 수행하는데 필요한 정보도 함께 알아야 할 책임이 있다.
  • 적절한 협력이 적절한 책임을 제공하고, 적절한 책임을 적절한 객체에게 할당해야만 단순하고 유연한 설계를 창조할 수 있다.

2.1.1 책임 할당

  • 자율적인 객체를 만드는 가장 기본적인 방법은 책임을 수행하는 데 필요한 정보를 가장 잘 알고 있는 전문가에게 그 책임을 할당하는 것이다.
    => Information Expert 패턴
  • 객체에게 책임을 할당하기 위해서는 먼저 협력이라는 문맥을 정의해야 한다.
    => 협력을 설계하는 출발점은 시스템이 사용자에게 제공하는 기능을 시스템이 담당할 하나의 책임으로 바라보는 것이다.
    => 객체지향 설계는 시스템의 책임을 완료하는 데 필요한 더 작은 책임을 찾아내고 이를 객체들에게 할당하는 반복적인 과정을 통해 모양을 갖춰간다.
  • 메시지는 메시지를 수신할 객체의 책임을 결정한다.
    => 이렇게 결정된 메시지가 객체의 퍼블릭 인터페이스를 구성한다.
  • 협력을 설계하면서 객체의 책임을 식별해 나가는 과정에서 최종적으로 얻게 되는 결과물은 시스템을 구성하는 객체들의 인터페이스와 오퍼레이션의 목록이다.
  • 기본적인 전략은 책임을 수행할 정보 전문가를 찾는 것이다.
    => 하지만 어떤 경우에는 응집도와 결합도의 관점에서 정보 전문가가 아닌 다른 객체에게 책임을 할당하는 것이 더 적절한 경우도 존재한다.

2.1.2 책임 주도 설계

  • 책임을 찾고 책임을 수행할 적절한 객체를 찾아 책임을 할당하는 방식으로 협력을 설계하는 방법
    => 책임 주도 설계(Responsibility-Driven Design, RDD)
  • 책임 주도 설계 방법의 과정
    • 시스템이 사용자에게 제공해야 하는 기능인 시스템 책임을 파악한다.
    • 시스템 책임을 더 작은 책임으로 분할한다.
    • 분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당한다.
    • 객체가 책임을 수행하는 도중 다른 객체의 도움이 필요한 경우 이를 책임질 적절한 객체 또는 역할을 찾는다.
    • 해당 객체 또는 역할에게 책임을 할당함으로써 두 객체가 협력하게 한다.
  • 책임을 할당할 때 고려해야 하는 두 가지 요소
    • 메시지가 객체를 결정한다.
    • 행동이 상태를 결정한다.

2.1.3 메시지가 객체를 결정한다

  • 객체에게 책임을 할당하는 데 필요한 메시지를 먼저 식별하고 메시지를 처리할 객체를 나중에 선택했다는 것이 중요하다.
    => 다시 말해, 객체가 메시지를 선택하는 것이 아니라 메시지가 객체를 선택하게 했다.
  • 메시지가 객체를 선택하게 해야 하는 두 가지 중요한 이유
    • 객체가 최소한의 인터페이스를 가질 수 있게 된다.
      => 필요한 메시지가 식별될 때까지 객체의 퍼블릭 인터페이스에 어떤 것도 추가하지 않기 때문에 객체는 애플리케이션에 크지도, 작지도 않은 꼭 필요한 크기의 퍼블릭 인터페이스를 가질 수 있다.
    • 객체는 충분히 추상적인 인터페이스를 가질 수 있게 된다.
      => 객체의 인터페이스는 무엇을 하는지는 표현해야 하지만 어떻게 수행하는지를 노출해서는 안된다.
      => 메시지는 외부의 객체가 요청하는 무언가를 의미하기 때문에 메시지를 먼저 식별하면 무엇을 수행할지에 초점을 맞추는 인터페이스를 얻을 수 있다.

2.1.4 행동이 상태를 결정한다

  • 객체가 존재하는 이유는 협력에 참여하기 위해서다.
    => 따라서 객체는 협력에 필요한 행동을 제공해야 한다.
  • 객체의 행동은 객체가 협력에 참여할 수 있는 유일한 방법이다.
    => 객체가 협력에 적합한지를 결정하는 것은 그 객체의 상태가 아니라 행동이다.
  • 얼마나 적절한 객체를 창조했느냐는 얼마나 적절한 책임을 할당했느냐에 달려있고, 책임이 얼마나 적절한지는 협력이 얼마나 적절한가에 달려있다.
  • 초보자의 가장 큰 실수는 먼저 객체에 필요한 상태가 무엇인지를 결정하고, 그 후에 상태에 필요한 행동을 결정한다.
    => 이런 방식은 객체의 내부 구현이 객체의 퍼블릭 인터페이스에 노출되도록 만들기 때문에 캡슐화를 저해한다.
    => 객체의 내부 구현을 변경하면 퍼블릭 인터페이스도 함께 변경되고, 결국 객체에 의존하는 클라이언트로 변경의 영향이 전파된다.
  • 객체의 내부 구현에 초점을 맞춘 설계 방법
    => 데이터 주도 설계(Data-Driven Design)
  • 캡슐화를 위반하지 않도록 구현에 대한 결정을 뒤로 미루면서 객체의 행위를 고려하기 위해서는 항상 협력이라는 문맥 안에서 객체를 생각해야 한다.
    => 개별 객체의 상태와 행동이 아닌 시스템의 기능을 구현하기 위한 협력에 초점을 맞춰야만 응집도가 높고 결합도가 낮은 객체들을 창조할 수 있다.
  • 중요한 것은 객체의 상태가 아니라 행동이다.
    => 협력이 객체의 행동을 결정하고 행동이 상태를 결정한다.
    => 그 행동이 바로 객체의 책임이 된다.
profile
상상을 현실로 만들기 위해 노력하는 개발자

0개의 댓글