5. 책임과 메시지
책임
객체지향 공동체를 구성하는 단위는 자율적인 객체이다.
자율적인 객체 : 스스로 정한 원칙에 따라 판단하고 스스로의 의지를 기반으로 행동하는 객체
객체가 어떤 행동을 하는 유일한 이유는 다른 객체로부터 요청을 받았기 때문이다. 이 요청을 처리하기 위해 객체가 수행하는 행동을 책임이라고 한다.
과도하게 상세한 책임 - 협력의 최종 목표는 만족시킬지 몰라도 객체가 누려야 할 자유를 훼손
자율적인 책임 - 객체가 어떻게(how) 해야 하는가가 아니라 무엇(what)을 해야 하는가를 설명
추상적이고 포괄적인 책임은 협력을 좀 더 다양한 환경에서 재사용할 수 있도록 유연성이라는 축복을 내려준다.
그러나 책임은 협력에 참여하는 의도를 명확하게 설명할 수 있는 수준 안에서 추상적이어야 한다.
메시지
협력을 위해서는 객체들의 활발한 소통이 필요하며 이러한 소통을 위해 사용할 수 있는 유일한 의사소통 수단이 메시지이다.
같은 의미에서, 객체의 행동을 유발하는 행위를 메시지 전송이라 한다.
메시지의 구성
- 수신자 : 말 그대로 메시지를 받는 사람
- 메시지 이름 : 전송하는 메시지
- 인자 : 메시지를 전송할 때 필요한 추가적인 정보
앞서 설명했지만 여기서 또 강조하는 부분은 객체가 수신받은 메시지를 처리하기 위한 방법은 자율적으로 선택할 수 있다는 것이다. 외부의 객체는 메시지에 관해서만 볼 수 있고 객체 내부는 볼 수 없기 때문에 자연스럽게 객체의 내부와 외부가 분리된다.
위에서 '메시지를 처리하기 위한 방법'이 바로 메소드이다. 정확하게는 메시지를 처리하기 위해 내부적으로 선택하는 방법을 의미한다. 이는 자연스럽게 '다형성'으로 연결된다. 동일한 메시지가 오더라도 서로 다른 객체가 서로 다르게 반응하는 것을 의미한다.
메소드 : 메시지를 처리하기 위해 내부적으로 선택하는 방법.
메시지를 수신한 객체가 실행 시간에 메소드를 선택할 수 있다는 사실은 객체지향 프로그래밍을 차별화시키는 핵심적인 특징 중 하나이다. 절차 지향 프로그래밍은 프로시저 호출에 대한 실행 코드를 컴파일 시간에 결정한다.
다형성
: 서로 다른 유형의 객체가 동일한 메시지에 대해 서로 다르게 반응하는 것.
역할, 책임, 협력 측면에서, 서로 다른 역할을 가지는 객체들이 동일한 메시지에 대해 응답한다는 것은 동일한 책임을 가진다는 것을 의미한다. 메시지 송신자의 관점에서 바라보면, 메시지 수신자들을 따로 구분할 필요 없이 동일한 메시지를 보내기만 하면 된다. 자기들이 알아서 그들의 역할에 맞게 행동한다. 이는 기본적으로 다형성은 동일한 역할을 수행할 수 있는 객체들의 대체 가능성을 의미한다. 즉, 다형성은 수신자의 종류를 캡슐화한다. 다형성은 객체들간의 의존도나 결합력을 낮춘다. 객체 간 결합이 아닌 메시지를 통한 결합이기 때문이다.
객체지향의 기본 개념은 책임을 수행하는 자율적인 객체들의 협력을 통해 애플리케이션을 구축하는 것이다.
이 객체들이 협력하기 위한 유일한 수단은 메시지이기 때문에 결국 객체지향의 핵심은 메시지이다.
객체지향 애플리케이션은 클래스를 통해 구현되지만 메시지를 통해 정의된다. 클래스는 단지 구현 도구일 뿐이다.
이 책의 저자는 객체지향에 대해 설명할 때 클래스라는 단어가 우선시되는 것을 정말 싫어한다. 객체지향에 대한 좀 더 본질적인 해석을 알려준다.
클래스를 중심에 두는 설계는 유연하지 못하고 확장하기 어렵다. 객체지향 패러다임으로의 전환은 시스템을 정적인 클래스들의 집합이 아닌 메시지를 주고받는 동적인 객체들의 집합으로 바라보는 것에서 시작된다. 객체가 메시지를 선택하는 것이 아니라 메시지가 객체를 선택하게 해야 한다. 이를 위해서는 메시지를 중심으로 협력을 설계해야 한다.
책임주도설계
이제 책임 주도 설계를 다시 살펴보자.
객체지향 설계는 적절한 책임을 적절한 객체에게 할당하면서 메시지를 기반으로 협력하는 객체들의 관계를 발견하는 과정이고, 이처럼 책임을 완수하기 위해 협력하는 객체들을 이용해 시스템을 설계하는 방법을 책임 주도 설계라고 한다. 책임주도설계의 기본 아이디어는 메시지를 기반으로 적절한 역할과 책임, 협력을 발견하는 것이다.
What/Who Cycle
책임주도 설계의 과정을 What/Who 사이클이라고 한다. 객체 사이의 협력 관계를 설계하기 위해 먼저 어떤 행위(What)를 수행할 것인지 결정한 후에 누가(Who) 그 행위를 수행할 것인지 결정해야 한다는 것이다. 협력이라는 문맥 안에서 객체의 책임을 결정하는 것은 메시지이다. 책임이 먼저 오고 객체가 그 책임을 따른다. 결과적으로 시스템의 목표 행위는 객체들의 책임으로 분배된다.
What/Who Cycle은 역할을 수행할 객체의 인터페이스를 발견하기 위해 메시지를 이용하는 책임주도 설계의 핵심 아이디어를 명확하게 표현한다.
데메테르 법칙(Law of Demeter)
메시지를 먼저 결정하고 객체가 메시지를 따르게 하는 설계 방식은 객체가 외부에 제공하는 인터페이스가 독특한 스타일을 따르게 만든다. 이 스타일을 데메테르법칙(Law of Demeter)이라 한다. 이는 다른 말로 'Tell, Dont's ask', 묻지 말고 시켜라 스타일이라고도 하는데 말 그대로 송신자는 수신자가 어떤 객체인지 모르지만 자신이 전송한 메시지를 잘 처리할 것이라고 믿고 전송하는 것이다. 이는 객체지향은 자율적인 객체들의 공동체라는 것을 잘 드러낸다. 객체를 자율적으로 만들고 캡슐화를 보장하며 결합도를 낮게 유지시켜 결과적으로 설계를 유연하게 만들어준다.
인터페이스
: 어떤 두 사물이 마주치는 경계에서 서로 상호작용할 수 있게 이어주는 방법이나 장치. 객체가 외부로부터 메시지를 받기 위한 통로
특징
- 인터페이스 사용법만 익히면 내부 구조나 동작 방식을 몰라도 쉽게 대상을 조작하거나 의사를 전달할 수 있다.
- 단순히 내부 구성이나 작동 방식을 변경하는 것은 사용자에게 어떤 영향도 미치지 않는다.
- 대상이 변경되더라도 동일한 인터페이스를 제공하기만 하면 아무 문제없이 상호작용할 수 있다.
공용 인터페이스
: 내부에서만 접근 가능한 사적인 인터페이스와 구분하기 위해 외부에 공개된 인터페이스.
- 객체의 내부와 외부를 명확하게 분리한다.
객체지향적인 사고 방식을 이해하기 위해 중요한 세 가지 원칙.
1. 좀 더 추상적인 인터페이스
- '자율적인 책임'. 추상적인 수준의 메시지를 수신할 수 있는 인터페이스를 제공하면 수신자의 자율성을 보장할 수 있다.
2. 최소 인터페이스
- 외부에서 사용할 필요가 없는 인터페이스는 최대한 노출하지 마라.
-> 객체의 내부를 수정하더라도 외부에 미치는 영향을 최소화할 수 있다.
3. 인터페이스와 구현 간에 차이가 있다는 점을 인식
구현 : 내부 구조와 작동방식. 상태 변수와 메소드 같이 객체를 구성하지만 공용 인터페이스에 포함되지 않는 모든 것.
- 만약 객체의 모든 것이 외부에 공개되어 있다면 작은 부분을 수정하더라도 그 파급력은 거대해서 객체 공동체에 큰 파장을 일으키기 때문에 인터페이스와 구현을 분리하는 것은 매우 중요하다.
캡슐화 : 객체의 자율성을 보존하기 위해 구현을 외부로부터 감추는 것. 정보 은닉이라고도 부른다.
책임의 자율성이 협력의 품질을 결정하는 근거
- 자율적인 책임은 협력을 단순하게 만든다. 다른 말로 표현하면 책임이 적절하게 추상화된다.
- 자율적인 책임은 객체의 외부와 내부를 명확하게 분리한다.
- 책임이 자율적일 경우 책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않기 때문에 객체 간의 결합도가 낮아진다.
- 자율적인 책임은 협력의 대상을 다양하게 선택할 수 있는 유연성을 제공한다.
- 객체가 수행하는 책임들이 자율적일수록 객체의 역할을 이해하기 쉬워진다. 존재 이유가 명확하게 표현되기 때문이다.
'Book Report' 카테고리의 다른 글
객체지향의 사실과 오해 - 7장, 후기 (1) | 2022.03.15 |
---|---|
객체지향의 사실과 오해 - 6장 (0) | 2022.03.12 |
객체지향의 사실과 오해 - 4장 (0) | 2022.03.05 |
마지막 몰입 (0) | 2022.02.25 |
코로나 시대의 역발상 트렌드 (0) | 2022.02.20 |