본문 바로가기

개발이야기

객체 지향의 사실과 오해 | 4장

우리 모두를 합친 것보다 더 현명한 사람은 없다. - Ken Blanchard

 

협력이라는 문맥이 객체의 행동 방식을 결정한다. 

개별 객체가 아니라 객체들 사이에서 이뤄지는 협력이다.

협력이 자리를 잡으면 저절로 객체의 행동이 드러나고 뒤이어 적절한 객체의 상태가 결정된다.

 

객체의 모양을 빚는 것은 객체가 참여하는 협력이다.

어떤 협력에 참여하는지가 객체에 필요한 행동을 결정하고 필요한 행동이 객체의 상태를 결정한다. 

개별적인 객체의 행동이나 상태가 아니라 객체들 간의 협력에 집중하라.

협력

협력의 본질은 요청과 응답으로 연결되는 사람들의 네트워크이다.

다른 사람으로부터 요청을 받은 사람 역시 자신에게 주어진 일을 처리하던 도중 다른 사람의 도움이 필요할 수 있다.

결과적으로 협력은 다수의 요청과 응답으로 구성된다.

객체지향의 세계는 동일한 목적을 달성하기 위해 협력하는 객체들의 공동체이다.

 

객체가 특정 요청을 받아들일 수 있는 이유는 그 요청에 대해 적절한 방식으로 응답하는데 필요한 지식과 행동 방식을 가지고 있기 때문.

요청과 응답은 협력에 참여하는 객체가 수행할 책임을 정의한다.

책임

어떤 객체가 어떤 요청에 대해 대답해 줄 수 있거나, 적절한 행동을 할 의무가 있는 경우 해당 객체가 책임을 가진다고 말한다.

어떤 대상에 대한 요청은 그 대상이 요청을 처리할 책임이 있음을 암시한다.

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

 

책임은 객체에 의해 정의되는 응집도 있는 행위의 집합.

객체가 알아야하는 정보와 객체가 수행할 수 있는 행위에 대해 개략적으로 서술한 문장.

객체의 책임은 '객체가 무엇을 알고 있는가(knowing)'과 '무엇을 할 수 있는가(doing)'으로 구성.

 

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

 

객체 지향 설계의 예술은 적절한 ㅏ객체에게 적절한 책임을 할당하는데 있다. 명확한 책임이 애플리케이션의 미래를 결정한다.

책임은 객체의 외부에 제공해 줄 수 있는 정보(아는 것의 측면)와 외부에 제공해 줄  수 있는 서비스(하는 것의 측면)의 목록이다.

책임은 객체 지향의 공용 인터페이스(public interface)를 구성한다.

 

협력 안에서 객체는 다른 객체로부터 요청이 전송됐을 경우에만 자신에게 주어진 책임을 수행한다.

객체가 다른 객체에게 주어진 책임을 수행하도록 요청을 보내는 것을 메시지 전송(message-send)라고 한다. 

메시지를 전송함으로써 협력을 요청하는 객체를 송신자라고 하고 메시지를 받아 요청을 처리하는 객체를 수신자라고 한다.

 

객체지향 설계는 협력에 참여하기 위해 어떤 객체가 어떤 책임을 수행해야 하고 어떤 객체로부터 메시지를 수신할 것인지를 결정하는 것으로부터 시작된다.

어떤 클래스가 필요하고 어떤 메서드를 포함해야 하는지 결정하는 것은 책임과 메시지에 대한 대략적인 윤곽을 잡은 후에 시작해도 된다.

역할

결론적으로 어떤 객체가 수행하는 책임의 집합은 객체가 협력 안에서 수행하는 역할을 암시한다.

역할은 재사용 가능하고 유연한 객체지향 설계를 낳는 매우 중요한 구성요소이다.

역할을 대채할 수 있는 객체는 동일한 메시지를 이해할 수 있는 객체로 한정된다.

 

동일한 역할을 수행할 수 있다는 것은 해당 객체들이 협력 내에서 동일한 책임의 집합을 수행할 수 있다는 것을 의미한다.

동일한 역할을 수행하는 객체들이 동일한 메시지를 수신할 수 있기 때문에 동일한 책임을 수행할 수 있다.

역할의 개념을 사용하면 유사한 협력을 추상화해서 인지 과부화를 줄인다.

역할은 객체지향 설계의 단순성(simplicity), 유연성(flexiblity), 재사용성(reusability)을 뒷받침하는 핵심 개념이다.

 

역할의 가장 큰 가치는 하나의 협력 안에 여러 종류의 객체가 참여할 수 있게 함으로써 협력을 추상화할 수 있다는 것이다.

구체적인 객체로 추상적인 역할을 대체해서 동일한 구조의 협력을 다양한 문맥에서 재사용할 수 있는 능력. (객체 지향의 힘)

이 힘은 근본적으로 역할의 대체 가능성에서 비롯된다.

대체 가능성

역할은 협력 안에서 구체적인 객체로 대체될 수 있는 추상적인 협력자다.

객체가 역할을 대체 가능하기 위해서는 협력 안에서 역할이 수행하는 모든 책임을 동일하게 수행할 수 있어야한다.

 

객체의 타입과 역할 사이에는 일반화/특수화 관계가 성립하는 것이 일반적이다. 

역할이 협력을 추상적으로 만들 수 있는 이유는 역할 자체가 객체의 추상화이기 때문이다.

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

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

객체가 존재하는 이유는 행위를 수행하며 협력에 참여하기 위해서이다. 중요한 것은 객체의 행동, 즉 책임이다.

클래스는 단지 시스템에 필요한 객체를 표현하고 생성하기 위해 프로그래밍언어가 제공하는 구현 메커니즘이다.

객체지향의 핵심은 객체가 협력 안에서 어떤 책임과 역할을 수행할 것인지를 결정하는 것이다. 

객체를 섬으로 바라보지 말자.

 

올바른 객체를 설계하기 위해서는 견고하고 깔끔한 협력을 설계해야한다. 

협력을 설계한다는 것은 설계에 참여하는 객체들이 주고받을 요청과 응답의 흐름을 결정하는 것을 의미.

객체가 협력에 참여하기 위해 필요한 데이터와 행동이 어느정도 구현된 후에 클래스의 구현방법을 결정해야한다.

 

객체지향이 올바른 객체에 올바른 책임을 할당하는 것과 관련된 모든 것이라면,

협력이라는 문맥 안에서 객체를 생각하는 것은 올바른 객체지향 애플리케이션을 구현하는 것과 관련된 모든 것이다.

 

각 객체가 가져야 하는 상태와 행위에 대해 고민하기 전에 그 객체가 참여할 문맥인 협력을 정의하라.

객체지향 설계 기법

  • 책임 주도 설계
    • 협력에 필요한 책임들을 식별하고 적합한 객체에게 책임을 할당하는 방식으로 애플리케이션을 설계한다
  • 디자인 패턴
    • 전문가들이 반복적으로 사용하는 해결 방법을 정의해 놓은 설계 템플릿의 모음
  • TDD
    • 테스트를 먼저 작성하고 테스트를 통과하는 코들르 추가하면서 애플리케이션을 완성하는 방법

책임 주도 설계

객체지향 시스템은 역할과 책임을 수행하는 자율적인 객체들의 공동체이다.

객체지향 설계란 애플리케이션의 기능을 구현하기 위한 협력 관계를 고안하고,

협력에 필요한 역할과 책임을 식별한 후 이를 수행할 수 있는 적절한 객체를 식별해 나가는 과정이다. 

 

책임을 여러 종류의 객체가 수행할 수 있다면 협력자는 객체가 아니라 추상적인 역할로 대체된다.

책임-주도 설계에서는 시스템 책임을 객체의 책임으로 변환하고,

각 객체가 책임을 수행하는 중에 필요한 정보나 서비스를 제공해줄 협력자를 찾아 협력자에게 책임을 할당하는 순차적인 방식으로 객체들의 협력 공동체를 구축.

디자인 패턴

디자인 패턴은 책임 주도 설계의 결과를 표현한다.

패턴은 특정한 상황에서 설계를 돕기 위해 모방하고 수정할 수 있는 과거의 설계 경험이다.

디자인 패턴은 반복적으로 발생하는 문제와 그 문제에 대한 해법의 쌍으로 정의된다.

디자인 패턴은 유사한 상황에서 반복적으로 적용할 수 있는 책임-주도 설계의 결과물.