Ch.3 역할, 책임, 협력

Previously...

  • 2장에서는 객체지향 프로그래밍의 다양한 요소와 구현 기법을 살펴봤다.

    • 클래스, 추상 클래스, 인터페이스의 조합으로 객체지향 프로그램을 구조화하는 기본적인 방법

    • 상속을 이용해 다형성을 구현하는 기법

      • 다형성이 지연 바인딩이라는 메커니즘을 통해 구현된다는 사실

      • 상속은 코드를 재사용할 수 있는 가장 널리 알려진 방법이지만 캡슐화 측면에서 합성이 더 좋다는 사실

  • 유연한 객체지향 프로그래밍을 위해서는 컴파일 시간 의존성실행 시간 의존성이 달라야 한다는 사실

객체지향 패러다임

  • 핵심 - 역할(role), 책임(responsibility), 협력(collaboration)

  • 본질 - 협력하는 객체의 공동체를 창조하는 것

    • 객체지향 설계의 핵심은 협력을 구성하기 위해 적절한 객체를 찾고 적절한 책임을 할당하는 과정에서 드러난다.

    • 클래스와 상속은 객체들의 책임과 협력이 어느 정도 자리를 잡은 후에 사용할 수 있는 구현 메커니즘일 뿐이다. 너무 이른 시기에 구현에 초점을 맞추면 변경하기 어렵고 유연하지 못한 코드를 낳을 수 있다.

객체지향에서 가장 중요한 것은 역할, 책임, 협력이다.

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

협력, 책임, 역할

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

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

  • 역할 - 객체들이 협력 안에서 수행하는 책임들이 모여 객체가 수행하여 구성되는 것

협력

  • 두 객체 사이의 협력은 하나의 객체가 다른 객체에게 도움을 요청할 때 시작된다.

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

    • 객체는 다른 객체의 내부 구현에 직접 접근할 수 없으므로 오직 메시지 전송을 통해서만 요청을 전달할 수 있다.

  • 메시지를 수신한 객체는 메서드를 실행해 요청에 응답하는데, 여기서 중요한 점은 객체가 메시지를 처리할 방법을 스스로 선택한다는 것이다.

    • 이는 객체가 자신의 일을 스스로 처리할 수 있는 자율적인 존재라는 뜻이다.

협력의 중요성

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

✅ 객체의 행동을 결정하는 것은 객체가 참여하고 있는 협력이다.

  • 협력이 바뀌면 객체가 제공하는 행동도 바뀌어야 한다.

  • 협력이 존재하기 때문에 객체가 존재한다.

✅ 객체의 상태를 결정하는 것행동이다.

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

  • 객체는 자신의 상태를 스스로 결정하고 관리하는 자율적인 존재이므로 행동에 필요한 상태도 함께 갖고 있어야 한다.

결과적으로 협력이 객체를 구성하는 행동과 상태를 모두 결정한다.

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

책임

  • 책임 - 협력에 참여하기 위해 객체가 수행하는 행동

  • 크레이그 라만(Craig Larman)은 책임을 크게 두 가지로 나눈다.

    • 하는 것(doing)

      • 객체를 생성하거나 계산을 수행하는 등 스스로 하는 것

      • 다른 객체의 행동을 시작시키는 것

      • 다른 객체의 활동을 제어하고 조절하는 것

    • 아는 것(knowing)

      • 사적인 정보에 관해 아는 것

      • 관련된 객체에 관해 아는 것

      • 자신이 유도하거나 계산할 수 있는 것에 관해 아는 것

책임의 중요성

  • 일반적으로 책임과 메시지의 크기는 다르다.

    • 책임은 객체가 수행할 수 있는 행동을 간략하게 서술하므로 메시지보다 추상적이고 개념적으로 크다.

크레이그 라만은 "객체지향 개발에서 가장 중요한 능력은 책임을 능숙하게 소프트웨어 객체에 할당하는 것"이라는 말로 책임 할당의 중요성을 강조했다.

객체지향 설계에서 가장 중요한 것책임이다.

책임 할당

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

  • 객체지향 설계는 협력에 필요한 메시지를 찾고 메시지에 적절한 객체를 선택하는 반복적인 과정을 통해 이뤄진다. 그리고 이런 메시지가 메시지를 수신할 객체의 책임을 결정한다.

이렇게 결정된 메시지가 객체의 퍼블릭(public) 인터페이스를 구성한다.

책임 주도 설계

책임 주도 설계(Responsibility-Driven Design, RDD) - 책임을 갖고 책임을 수행할 적절한 객체를 찾아 책임을 할당하는 방식으로 협력을 설계하는 방법

책임 주도 설계 방법의 과정

  • 시스템이 사용자에게 제공해야 하는 기능인 시스템 책임을 파악한다.

  • 시스템 책임을 더 작은 책임으로 분할한다.

  • 분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당한다.

  • 객체가 책임을 수행하는 도중 다른 객체의 도움이 필요한 경우 이를 책임질 적절한 객체 또는 역할을 찾는다.

  • 해당 객체 또는 역할에게 책임을 할당함으로써 두 객체가 협력하게 한다.

메시지가 객체를 결정한다

객체가 메시지를 선택하는 것이 아니라 메시지가 객체를 선택하게 한다.

이래야 하는 중요한 두 가지 이유는:

  • 객체가 최소한의 인터페이스(minimal interface)를 가질 수 있게 된다.

  • 객체가 충분히 추상적인 인터페이스(abstract interface)를 가질 수 있게 된다. (WHAT, but not HOW)

행동이 상태를 결정한다

  • 상태에 초점을 맞추고 설계하면 객체의 내부 구현이 객체의 퍼블릭 인터페이스에 노출되도록 만들기 때문에 캡슐화를 저해한다. 이렇게 객체의 내부 구현에 초점을 맞춘 설계 방법을 데이터-주도 설계(Data-Driven Design)라고 부른다.

역할

  • 역할 - 객체가 어떤 특정한 협력 안에서 수행하는 책임의 집합.

유연하고 재사용 가능하게 설계하려면 객체가 아닌 책임에 초점을 맞춰야 한다.

역할을 구현하는 가장 일반적인 방법은 추상 클래스인터페이스를 사용하는 것이다.

추상화를 이용한 설계는 두 가지 장점을 갖는다.

  • 추상화 계층만을 이용하면 중요한 정책을 상위 수준에서 단순화할 수 있다.

  • 설계가 좀 더 유연해진다.

My Thoughts So Far

  • 지금까지 책임 주도 설계보단 데이터-주도 설계를 많이 했던 것 같아 반성하게 된다...

  • 객체를 결정하기 위해서는 메시지를 결정해야 한다 -- 즉 어떤 책임을 갖고 행동을 할 지를 결정해야 상태도 결정할 수 있다는 것이 맞는 말인 것 같다. 근데 개발할 때 큰 그림을 그려보려고 해도 잘 안돼서 성미 급하게 좀 더 쉽고 덜 골치아프게 시작할 수 있는 데이터-주도 설계로 이어진 것 같다.

  • 구현이 아닌 추상을 강조하는 챕터이다 보니 한 번에 어려운 말들의 연속이었긴 한데 대충 이해는 가는 것 같다.

Last updated