협력이 객체를 결정한다
전통적인 경제학은 인간을 '이기적인 동시에 합리적인 존재'라고 칭한다.
그러나 다수의 실험 결과는 그렇지 않다.
인간의 본성은 이기적이고 합리적이지만, 행동을 결정하는 건 이런 본성이 아닌 문맥(context)이다.
인간이 어떤 상황에 처해있는지가 인간의 행동을 결정한다.
객체지향 세계에서도 마찬가지로 협력이라는 문맥이 객체의 행동 방식을 결정한다.
중요한 것은 개별 객체가 아닌, 객체들 사이에 이뤄지는 협력이다.
협력이 자리를 잡으면 저절로 객체의 행동이 드러나고, 뒤이어 객체의 상태가 결정된다.
협력에서 발생하는 책임
협력은 혼자만의 힘으로 문제를 해결하기 어렵기 때문에 발생하고, 요청과 응답으로 구성된다.
요청은 또 다른 요청을 연쇄적으로 발생시키기도 한다.
요청과 응답의 개념을 조금 더 깊게 생각해보면,
요청이 발생하는 이유는 해당 객체가 그 요청에 따라 무언가를 수행할 책임이 있기 때문이다.
응답이 발생하는 이유는 그 요청에 대해 적절한 방식으로 응답하는 데 필요한 지식과 행동을 가지고 있기 때문이다.
즉, 요청과 응답은 협력에 참여하는 객체가 수행할 책임을 정의한다.
책임은 1. 하는 것과 2. 아는 것으로 구분된다.
즉, 객체의 책임은 1. 외부에 제공해 줄 수 있는 서비스(하는 것) 2. 외부에 제공해 줄 수 있는 정보(아는 것)으로 구성된다.
책임이 수행되는 이유는 방식은 메세지다.
메세지가 수신되었을 때에만 (요청이 수신되었을 때에만) 해당 객체의 책임이 수행된다.
즉, 메세지 전송이란, 다른 객체에게 주어진 책임을 수행하도록 요청을 보내는 것이라 생각할 수 있다.
단, 메세지와 책임의 수준이 대응된다는 것은 아니다.
실제 협력에서는 하나의 책임이 여러 메세지로 분할되는 것이 일반적이다.
역할
역할은 책임의 집합을 의미한다.
역할의 개념이 왜 필요한가? 대체가능성 때문이다.
역할을 정의하는 것은 재사용 가능하고 유연한 객체지향 설계를 낳는다.
카페에서 바리스타가 어떤 사람이든, 손님이 어떤 직장을 다니고 있든 상관이 없다.
각자의 정해진 역할을 수행하기만 하면 주어진 협력을 완수해 '커피 전달' 이라는 목적을 달성할 수 있다.
이처럼 역할을 사용하면 여러 개의 협력을 하나의 협력으로 추상화할 수 있다.
반대로 이야기하면 역할을 수행하기만 하면 어떤 객체가 와도 상관이 없다.
그렇다고 해서 모든 객체가 특정 역할을 수행할 수 있다는 것은 아니다.
역할을 수행할 수 있다는 것은 메세지를 동일한 방식으로 이해할 수 있다는 것을 의미한다.
역할의 가장 큰 장점은 협력을 추상화할 수 있다는 것이다.
이는 애플리케이션에게 단순성, 유연성, 재사용성을 부여한다.
이는 역할의 대체가능성에서 온다.
대체가능성이란 무엇을 의미하는가?
앞서 말했듯 역할을 수행할 수만 있다면(메세지를 동일한 방식으로 이해할 수 있다면) 객체가 대체 가능하다는 말이다.
그러나 객체가 해당 역할만 수행할 필요는 없다.
객체는 주어진 책임 이외에 다른 책임을 수행해도 된다.
바리스타는 커피를 제조할 책임이 있지만, 가장의로서의 책임, 자식으로서의 책임도 존재한다.
이처럼 객체의 타입과 역할 사이에는 일반화/특수화 관계가 성립한다.
객체의 모양을 결정하는 것은 협력이다
객체지향 설계의 핵심은 협력을 결정짓는 것이다.
협력이 아닌 객체 그 자체, 혹은 데이터를 중심으로 설계하면 적절한 협력을 만들어내기 어렵다.
1. 우선 협력을 설계하고(요청과 응답의 흐름을 결정하고),
2. 이렇게 결정된 요청과 응답의 흐름을 객체가 협력에 참여하기 위해 수행할 책임으로 분류하고,
3. 이런 책임들을 적절한 객체에 할당한다.
4. 책임을 통해 객체 외부에 제공할 행동(인터페이스)을 구성한다.
4. 그리고 객체의 상태(데이터)를 결정한다.
객체지향 시스템에서 가장 중요한 것은 충분히 자율적인 동시에 충분히 협력적인 객체를 창조하는 것이며,
그러기 위해서는 객체를 우선 충분히 협력적으로 만든 후에
협력이라는 문맥 안에서 객체를 충분히 자율적으로 만드는 것이다.
객체지향 설계 기법
역할, 책임, 협력을 통해 객체지향 설계를 할 때 유용한 세 가지 기법이 있다.
1. 책임 주도 설계(Responsibility-Driven Design, RDD)
책임 주도 설계는 역할, 책임, 협력을 통해 설계하는 것을 목표로 한다.
시스템의 책임을 객체의 책임으로 변환하고, 각 객체가 책임을 수행하는 중 적절한 협력자를 찾아 책임을 할당하는 방식으로
객체들의 공동 협력체를 구상한다.
2. 디자인 패턴
'바퀴를 재발명하지 마라' 라는 말처럼, 이미 역할, 책임, 협력을 고안하기 위한 방법과 절차를 제시하고 있다.
디자인 패턴은 특정 클래스를 사용하라는 이야기를 하지 않는다.
여러 디자인 패턴들은 '역할'을 기준으로 설명되며, 해당 '역할'을 수행할 수 있는 객체라면 아무 객체든 상관이 없다.
3. 테스트 주도 개발(Test-Driven Development, TDD)
TDD는 응집도가 높고 결합도가 낮은 클래스로 구성된 시스템을 개발할 수 있게 하는 최상의 프랙티스이다.
그러나 TDD는 책임 주도 설계의 기본 개념을 따른다.
그렇기에 역할, 책임, 협력에 대한 이해가 제대로 수반되었을 때에만 좋은 효율을 발휘할 수 있다.
'객체지향' 카테고리의 다른 글
[객체지향의 사실과 오해] 6장: 객체 지도 (0) | 2023.02.23 |
---|---|
[객체지향의 사실과 오해] 5장: 책임과 메세지 (0) | 2023.01.14 |
[객체지향의 사실과 오해] 3장: 타입과 추상화 (0) | 2023.01.12 |
[객체지향의 사실과 오해] 2장: 이상한 나라의 객체 (0) | 2023.01.11 |
[객체지향의 사실과 오해] 1장: 협력하는 객체들의 공동체 (0) | 2023.01.10 |