3장. 역할. 책임, 협력
3.1 2장 리뷰
객체 지향 프로그램의 요소
: 클래스, 추상 클래스, 인터페이스
다형성
: 지연바인딩을 통해 구현
: 상속 / 합성 사용
: 유연성을 위해 합성이 권장된다.
3.2 3장 핵심 키워드
역할(role), 책임(responsibility), 협력(collaboration)
- 협력 : 객체간의 상호작용
- 책임: 두 객체가 협업을 하는 과정에서 각자 맡은 일
- 역할: 한 객체가 맡은 책임의 집합
3.3 협력
정의
객체들이 애플리케이션의 기능을 구현하기 위해 수행하는 상호작용
메시지 전송(message sending) vs 메서드 (method)
- screening은 movie에게 가격 계산을 "요청"한다. (메시지 전송)
- movie는 요청받은 일을 수행하기 위해, 내부 구현을 수행한다. (메서드 실행)
메시지 전송의 궁극적 목적은 객체의 자율성을 높이는 것이다.
협력, 행동, 내부 상태값 설계 순서
WRONG: 우리는 흔히, (1)객채의 필드를 정의하고, (2)메서드를 만든후, (3)협력을 생각한다.
RIGHT: (1)협력을 생각하고 (2)도메인(=객체) 정의 (3) 각 객체의 행동 정의 (4) 행동에서 유지해야할 상태값을 설정하는 것이 맞다.
협력은 객체를 설계하는데 필요한 일종의 문맥(context)를 제공한다.
3.4 책임
정의
협력에서 객체가 수행하는 행동
객체의 책임을 설계할 때 좋은 방법 : CRC 카드를 활용하자
: Candidate, Responsibity, Collaborator (= 후보, 책임, 협력)
: 세부 구현에 집착하기보다는 각 객체의 역할에 집중할 수 있다.
Information Expert(정보 전문가) 패턴
: 업무 수행하는데 필요한 정보을 가장 잘 아는 전문가에게 그 책임을 할당하자
책임 주도 설계 (Responsibility-Driven Design, RDD)
책임을 수행할 객체에게 책임 할당하는 방식
cf. 데이터 주도 설계 (Date-Driven Design)
메시지가 객체를 결정해야하는 이유
: 객체가 보낼 메시지에 기반하여 설계를 하면 좋은점
- 객체는 최소한의 인터페이스(minimal interface)를 가진다.
- 객체는 추상적인 인터페이스(abstract interface)를 가진다.
3.5 역할
정의
객체가 특정한 협력 안에서 수행하는 책임의 집합
설계시 역할을 고려하는 이유
유연하고 재사용 가능한 협력을 만들어 내기 위해서이다.
영화의 할인정책을 예시로 보자.
- (1) 몇 퍼센트를 할인합니다.
- (2) 얼마를 할인합니다
위 두가지의 공통점은 "할인한다"는 역할이다. 역할을 인터페이스로 정의하고, 세부 구현은 구현체에 맡기면 유연한 설계가 이뤄진다.
역할의 이름을 정할 때 주의사항
추상적이어야한다. 특정 행동에 한정된 객체면 안된다.
예를 들어 DiscountPolicy는 AmountDiscountPolicy 와 PercetDiscountPolicy를 모두 포함한다.
역할의 구현법
- 추상 클래스
- 인터페이스
역할을 뽑아내는 방법
(1) 기능의 큰 그림 파악
: 애플리케이션의 큰 흐름, 시나리오를 먼저 파악하자. 그 안에서 큰 역할을 나누고, 기능을 구현하면 세부 역할이 나온다. 객체 구현은 그 다음이다.
(2) 동일한 협력을 하는 객체를 하나로 합쳐 추상화하자.
설계초기에는 여러객체에 직접 책임을 할당한다. 추후 비슷한 협력을 하나로 합쳐, 객체를 역할로 대체할 수 있다.
객체는 여러 역할을 가진다
역할은 협력에서 드러나는 특성이다. 고로 다른 협력에서는 또다른 역할을 가진다.
객체:역할 = 배우:배역 으로 생각하자.
3.6 역할 기반 추상화의 장점
1) 추상화 계층만을 이용하면, 중요한 정책을 상위 수준에서 단순화 할 수 있다.
2) 설계가 유연해진다.