자율적인 책임
훌륭한 객체지향의 세계는 명확하게 정의된 역할과 책임을 지닌 객체들이 상호 협력하는 세계다.
즉, 자율적인 객체가 상호 협력하는 세계이다.
자율성이란?
'자기 스스로의 원칙에 따라 어떤 일을 하거나 자신을 통제해서 절제하는 성질'이나 특성을 의미한다.
적절한 책임은 자율적인 객체를 낳고, 자율적인 객체들이 모여 유연하고 단순한 협력을 낳는다.
따라서 협력에 참여하는 객체가 얼마나 자율적인지가 전체 애플리케이션의 품질을 결정한다.
이상한 나라의 엘리스 이야기에서 왕이 증인들을 불러 증언하라고 하는 내용이 나온다.
이 이야기에서 중요한 점은, 왕은 증인석에 앉은 인물이 누가 되었든 간에 '중언하라'라고 말할 뿐이라는 점이다.
'증언하라' 라는 메세지는 증인의 자율성을 충분히 보장한다.
어떻게 증언하는지는 상관이 없다. 단순히 '증언하라' 라는 메세지에 응답하기만 하면 된다.
글을 써서 증언하든, 말로 증언하든 상관이 없다는 것이다.
반대로 자율성이 없는 경우는 어떤 경우일까?
'지난 00일, 0시, 어디에서 무엇을 했는지 말해라.'
이런 경우 증인은 증언할 방법을 충분히 자율적으로 선택할 수 없다.
즉, 책임은 적절히 추상적이어야 객체의 자율성을 보장할 수 있다.
'어디에서 무엇을, 어떻게를 증언하는 것'으로 책임을 정의할 수도 있지만, 자율성을 위해 '증언하는 것'을 책임으로 정의한다는 것이다.
책임은 어떻게 정의되어야 하는가?
자율성을 위해 책임을 추상적으로 조절할 수 있다고 했다.
단순히 '증언하는 것'을 책임으로 정의해 증인의 자율성을 보장할 수 있었다.
그러면 얼마나 추상적이어야 하는가?
'증언하는 것'이 아닌 '설명하는 것'이 책임으로 정의된다면? 무엇을 설명해야 하는가?
이 경우 너무 추상적이기에 무엇을 설명할지 책임이 오히려 모호해진다.
따라서 적절하게 추상적인 책임이 중요하다. 책임은 협력에 참여하는 의도를 내포해야 한다.
또한 자율적인 책임은 '어떻게(how)'가 아닌 '무엇(what)'을 해야 하는가를 설명해야 한다.
'어디서, 몇시에, 무엇을 했는지 증언하라'와 같은 내용은 어떻게(how)를 정의하고 있기 때문에 자율적인 객체를 기대하기 어렵다.
메세지와 메서드
적절한 책임, 즉 자율적인 책임이 부여되어야 자율적인 객체를 만들어낼 수 있고 유연하고 단순한 협력을 만들 수 있다고 이야기했다.
책임에는 '어떤 행동을 수행한다'는 의미가 내포되어 있다.
객체가 어떤 행동을 수행하는 기준은 다른 객체로부터 요청을 수신했을 때 뿐이다.
객체가 다른 객체에게 접근할 수 있는 유일한 방법은 요청을 보내는 것이고, 이 요청을 메세지라고 한다.
메세지는 메세지 이름, 인자로 구성되고
메세지 전송은 수신자와 메세지의 조합으로 구성된다. 즉, 다음과 같은 형태로 구성된다.
모자장수.증언하라(어제, 왕국)
메세지의 개념은 책임의 개념과 연결된다.
어떤 객체가 수신할 수 있는 메세지의 모양이 객체가 수행할 책임의 모양을 결정한다.
객체가 메세지를 수신할 수 있다는 것은 객체가 메세지에 해당하는 책임을 수행할 수 있다는 것을 의미한다.
그리고 객체는 메세지를 처리하기 위한 방법을 자율적으로 선택할 수 있고, 이것을 메서드라고 한다.
메세지는 '무엇'을 명시하며, 메서드는 '어떻게'를 명시한다.
메서드를 선택하는 것은 전적으로 해당 객체의 책임이다.
'무엇'이 실행될지는 외부에서 명시하지만, '어떻게' 수행할 것인지는 내부에서 메소드로 결정한다.
이 개념을 통해 다형성을 쉽게 이해할 수 있다.
다형성의 한 예는 다음과 같다.
증인석에 앉은 사람이 모자 장수이든, 엘리스이든, 누구이든 간에 '증인' 이라는 역할을 가지기만 하면 상관 없다.
'증언하라' 라는 메세지를 이해할 수 있기 때문이다. 각자 증언하는 방법이 다를지라도 말이다.
다형성은 대체가능성을 의미한다.
다형성은 송신자와 수신자 간의 객체 타입에 대해 결합도를 낮춘다.
결합도가 낮을 때의 이점
송신자는 메세지만 안다. 수신자에 관해서는 전혀 모른다.
이런 상황은 송신자와 수신자가 결합도가 낮다고 이야기할 수 있다.
그러면 왜 이런 상황이 좋은걸까?
송신자가 수신자에 대해 매우 적은 정보만 알고 있더라도 협력이 가능하므로,
- 협력이 유연해진다. 송신자는 메세지를 받는 대상을 고려하지 않아도 된다. 단순히 메세지만 알면 된다. 따라서 협력을 쉽게 변경할 수 있다.
- 협력이 수행되는 방식을 확장할 수 있다. 송신자에게 아무 영향을 미 치지 않고 수신자를 교체할 수 있게 된다.
- 협력이 수행되는 방식을 재사용할 수 있다. 즉, 하나의 디자인 패턴이나 템플릿처럼 '왕 - 증인' 구조의 재판을 다양한 문맥에서 사용할 수 있다.
메세지는 송신자와 수신자를 약하게 연결해야 한다. 이것이 1. 설계를 유연하게 하고, 2. 확장 가능하게 하며, 3. 재사용 가능하게 하는 비결이다.
결국은 메세지가 핵심이다
객체지향의 핵심은 메세지다.
책임을 수행하는 자율적인 객체들의 협력을 통해 애플리케이션을 구축하는 것이 객체지향의 기본 개념이다.
협력은 메세지로만 이루어진다. 메세지의 수신 여부는 책임을 정의한다.
객체지향 설계의 중심에는 메세지가 위치한다.
객체가 메세지를 선택하는 것이 아닌, 메세지가 객체를 선택해야 한다.
메세지가 객체를 선택하게 만들려면 메세지 중심으로 협력을 설계해야 한다.
책임 주도 설계(RDD)가 그 대표적인 예이다.
책임 주도 설계에서는 What/Who 사이클을 따른다.
어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하라는 것이다.
이런 사이클을 다르다 보면, 객체 사이의 협력 방식을 특징짓는 한 가지 스타일에 이르게 된다.
송신자는 수신자가 애초에 정해져 있지 않으므로(행위를 먼저 정의하기에)
수신자에 대해 자연스럽게 꼬치꼬치 캐묻을 수 없게 되고, 단순히 메세지를 잘 처리할 것이라 믿고 전송한다.
이러한 스타일의 협력 패턴은 '묻지 말고 시켜라(Tell, Don't Ask, TDA)로 널리 알려져 있다.
TDA 스타일은 객체를 자율적으로 만들고 캡슐화를 보장하며 결합도를 낮게 유지시켜 주기 때문에 설계를 유연하게 만든다.
이처럼 메세지는 협력의 핵심이다. 메세지를 믿으면 자율적인 책임은 저절로 따라오게 된다.
객체 인터페이스
인터페이스란 무엇일까?
어떤 두 사물이 마주치는 경계 지점에서 서로 상호작용할 수 있게 이어주는 방법이나 장치를 의미한다.
인터페이스는 세 가지 특성을 가진다.
- 인터페이스의 사용법을 익히기만 하면 내부 구조나 동작 방식을 몰라도 쉽게 대상을 조작할 수 있다.
- 인터페이스 자체는 변경하지 않고 단순히 내부 구성이나 작동 방식만을 변경하는 것은 사용자에게 영향을 미치지 않는다.
- 대상이 변경되더라도 동일한 인터페이스를 제공하기만 하면 아무 문제 없이 상호작용할 수 있다.
협력에 참여하는 객체도 마찬가지로 인터페이스를 제공한다.
그리고 인터페이스가 결정되는 기준은 메세지와 책임이다.
그리고 인터페이스를 정의하는 것은 객체의 내부와 외부를 분리하게 해준다.
내부와 외부를 분리한다는 의미는 객체의 공용 인터페이스와 구현을 분리한다는 것과 동일하다.
왜 객체의 내부와 외부를 분리하는 것이 중요한가?
변경에 대한 안전지대를 만들기 위함이다.
객체의 모든 것이 외부로 공개되어 있으면 아무리 작은 것을 수정하더라도 파급 효과가 크다.
따라서 구현을 내부로 숨겨 변경에 대한 안전지대로 만드는 것이 중요하다.
객체 외부에 영향을 미치는 변경은 공용 인터페이스를 수정할 때뿐이어야 한다.
인터페이스와 구현을 분리한다는 것은 변경될 만한 부분을 객체의 내부에 꽁꽁 숨겨 놓는다는 것을 의미한다.
일반적으로 이 원칙을 수행하기 위한 객체 설계 방법을 캡슐화라고 한다.
그래서 자율적인 책임이 왜 중요한가?
앞서 자율적인 책임이 중요하고, 메세지는 책임을 가질 객체를 식별하게 해주며,
객체는 변경에 내성을 가지기 위해 인터페이스를 가진다고 했다.
- 자율적인 책임은 협력을 단순하게 만든다. 단순히 '증언하라' 라고 하면 되지, '무엇을 어떻게, 언제'라고 세세히 짚어줄 필요가 없다.
- 자율적인 책임은 객체의 외부와 내부를 명확하게 구분한다. 즉, 요청하는 객체가 몰라도 되는 사적인 부분이 캡슐화되어 인터페이스와 구현이 분리된다.
- 책임이 자율적일 경우 책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않는다.
- 자율적인 책임은 협력의 대상을 다양하게 선택할 수 있게 한다.
- 객체가 수행하는 책임들이 자율적일수록 객체의 역할을 이해하기 쉬워진다. 책임이 모호하다고 하면, 협력에서 객체의 정체성을 잃기쉽다. 반대로 책임이 명확하다면 응집도가 높은 상태를 유지하기가 쉽다.
객체지향의 강력함을 누리기 위한 출발점은 책임을 자율적으로 만드는 것이다.
그리고 이것은 선택하는 메세지에 따라 달라진다.
'객체지향' 카테고리의 다른 글
왜 상태와 행위를 한 곳에서 관리해야할까? (4) | 2023.03.19 |
---|---|
[객체지향의 사실과 오해] 6장: 객체 지도 (0) | 2023.02.23 |
[객체지향의 사실과 오해] 4장: 역할, 책임, 협력 (0) | 2023.01.13 |
[객체지향의 사실과 오해] 3장: 타입과 추상화 (0) | 2023.01.12 |
[객체지향의 사실과 오해] 2장: 이상한 나라의 객체 (0) | 2023.01.11 |