오브젝트 #3

문승현·2022년 9월 8일
0

BeDev_4

목록 보기
4/5
post-thumbnail

2장에서는 클래스, 추상 클래스, 인터페이스를 조합해 객체지향 프로그램을 구조화하는 방법과
상속을 이용해 다형성을 구현하는 기법을 학습하였다.
그런데 책에서는 이러한 내용이 구현 측면에 치우쳐져 있다고 말하며,
객체지향 프로그래밍의 본질은 협력하는 객체들의 공동체를 구성하는 것에 있다고 말한다.

협력

협력이란 객체들이 애플리케이션의 기능을 구현하기 위해 수행하는 상호작용을 의미한다.
책에서는 협력이 객체지향의 세계에서 기능을 구현할 수 있는 유일한 방법이라 말한다.

그리고 객체 사이의 협력은 메시지 전송을 통해 이루어지며,
객체는 자신에게 할당된 책임을 수행하던 중 필요한 정보를 알지 못하거나 도움이 필요한 경우,
적절한 객체에게 메시지를 전송해서 협력을 요청한다고 말한다.
상기에서 Screening은 요금 계산을 위해 Movie에 calculateMovieFee 메시지를 전송한다.
요금 계산을 위한 기본 요금과 할인 정책을 가장 잘 알고 있는 객체가 Movie이기 때문이다.

애플리케이션 안에 어떤 객체가 필요하다면 해당 객체는 어떤 협력에 참여하고 있는 것이다.
그리고 객체가 협력에 참여할 수 있는 이유는 협력에 필요한 행동을 보유하고 있기 때문이다.
결론적으로 객체의 행동을 결정하는 것은 객체가 참여하고 있는 협력이다.

이렇게 객체의 행동을 결정하는 것이 협력이라면 객체의 상태를 결정하는 것은 행동이다.
객체의 상태는 그 객체가 행동을 수행하는 데 필요한 정보가 무엇인지로 결정된다.
Movie가 기본 요금인 fee와 할인 정책인 discountPolicy라는 인스턴스 변수를
상태의 일부로 포함하는 이유는 요금 계산 행동을 수행하는 데 이 정보들이 필요하기 때문이다.

상태는 객체가 행동하는 데 필요한 정보에 의해 결정되고
행동은 협력 안에서 객체가 처리할 메시지로 결정된다.
결과적으로 객체가 참여하는 협력이 객체를 구성하는 행동과 상태 모두를 결정한다.
즉, 협력은 객체를 설계하는 데 필요한 일종의 문맥을 제공한다.

책임

앞서 이야기하였듯, 객체 사이의 협력은 메시지를 통해 이루어진다.
따라서 협력에 필요한 메시지를 찾고, 메시지에 적절한 객체를 선택해야 한다.
이때, 메시지를 처리하기 위해 객체가 수행하는 행동을 책임이라 한다.

이처럼 객체가 협력에 적합한지를 결정하는 것은 그 객체의 상태가 아니라 행동이다.
상태는 단지 객체가 행동을 정상적으로 수행하기 위해 필요한 재료이다.
협력이 객체의 행동을 결정하고 행동이 상태를 결정, 그리고 그 행동이 바로 객체의 책임이다.

역할

객체가 어떤 특정한 협력안에서 수행하는 책임의 집합을 역할이라고 한다.
역할이 중요한 이유는 역할을 통해 유연하고 재사용 가능한 협력을 얻을 수 있기 때문이다.

아래 그림에서 Movie는 '가격을 계산하라'라는 메시지 처리를 위해 할인 요금이 필요하다.
따라서 '할인 요금을 계산하라'라는 메시지를 전송해 외부 객체에게 도움을 요청하고자 한다.
그런데 금액 할인 정책과 비율 할인 정책이라는 두 가지 종류의 가격 할인 정책이 존재한다.
즉, 메시지에 대해 두 객체(AmountDiscountPolicy, PercentDiscountPolicy)가 응답할 수 있다.

하지만 두 객체 모두 메시지에 응답하도록 만들면 대부분의 코드가 중복되고 말 것이다.
사실 책임의 관점에서 바라보면 두 객체 모두 '할인 요금 계산'이라는 동일한 책임을 수행한다.
따라서 다음과 같이 '할인 요금을 계산하라'라는 메시지에 응답할 수 있는 역할을 만들 수 있다.
역할을 구현하는 가장 일반적인 방법은 추상 클래스와 인터페이스를 사용하는 것이다.
협력의 관점에서 추상 클래스와 인터페이스는 책임의 집합을 서술한 것이다.

이처럼 역할은 두 가지의 객체를 포괄할 수 있는 일종의 추상화이며,
동일한 책임을 수행하는 역할을 기반으로 두 개의 협력을 하나로 통합할 수 있다.
책임과 역할을 중심으로 협력을 바라보는 것이 변경과 확장이 용이한 설계의 첫걸음이다.

0개의 댓글