반응형
오브젝트 03 - 역할, 책임, 협력
3.1 협력
객체지향의 핵심은 역할, 책임, 협력이다. 이를 고민하지 않은 채 구현에 초점을 맞추는 것은 변경하기 어렵고 유연하지 못한 코드를 낳는다.
3.1.1 영화 예매 시스템 돌아보기
- 객체지향 원칙을 따르는 애플리케이션의 제어 흐름은 하나에 의해 통제되지 않고 다양한 객체들 사이에 균형있게 분배된다.
- 다양한 객체들은 기능을 구현하기 위해 메시지를 주고 받으며 상호작용하는데 이를 협력이라고 한다.
- 객체가 협력에 참여하기 위해 수행하는 로직은 책임이라고 한다.
- 객체들이 협력 안에서 수행하는 책임들이 모여 객체가 수행하는 역할을 구성한다.
3.1.2 협력
- 두 객체 사이의 협력은 하나의 객체가 다른 하나에게 도음울 요청할 때 시작된다.
- 메시지 전송은 객체 사이의 협력을 위한 유일한 커뮤니케이션 수단이다.
- 메시지를 수신한 객체는 메서드를 실행해 요청에 응답한다.
- 메시지를 어떻게 처리할지는 메시지를 수신한 객체가 직접 결정한다 - 객체는 자율적인 존재
- screening이 Movie에게 처리를 위임하는 이유는 요금을 계산하는데 필요한 기본 요금과 할인 정책을 가장 잘 알고있기 때문이다.
- screening이 요금을 직접 계산한다면, 두 객체는 강결합 되고 Movie의 자율성이 훼손된다.
- 객체를 자율적으로 만드는 가장 기본적인 방법은 내부구현 캡슐화이다.
3.1.3 협력이 설계를 위한 문맥을 결정한다
- 애플리케이션에 객체가 필요하다면 그 이유는 협력에 참여하고 있기 때문이다.
- 그 객체가 협력에 참여할 수 있는 이유는 협력에 필요한 적절한 행동을 보유하고 있기 때문이다.
- 객체의 행동을 결정하는 것은 객체가 참여하는 협력이므로, 협력이 바뀌면 객체가 제공해야 하는 행동 역시 바뀌어야 한다.
Movie 객체
- 영화라는 단어를 들으면 대부분은 극장에서 영화를 상영하는 장면을 상상
- 자연스럽게 Movie 객체가 play라는 행동을 수행할 것이라고 기대
- 그러나 Movie에 포함된 메서드는 요금을 계산하는 행동과 관련
- 이것은 Movie가 영화를 예매하기 위한 협력에 참여하고 있기 때문
- 협력이라는 문맥을 고려하지 않고 Movie의 행동을 결정하는것은 아무 의미가 없다.
- 협력이 존재하기 때문에 객체가 존재
- 객체의 상태는 객체가 행동하는데 필요한 정보에 의해 결정된다
public class Movie {
private Money fee;
private DiscountPolicy discountPolicy;
public Money calculateMovieFee(Screening screening) {
return fee.minus(discountPolicy.calculateDiscountAmount(screening));
}
}
3.2 책임
3.2.1 책임이란 무엇인가
- 협력에 참여하기 위해 객체가 수행하는 행동을 책임이라고 부른다.
- 객체지향 설계에서 가장 중요한 것은 책임이다.
- 협력이 중요한 이유는 객체에게 할당할 책임을 결정할 수 있는 문맥을 제공하기 때문
- 책임이란 객체에 의해 정의되는 응집도 있는 행위의 집합
- 객체가 유지해야 하는 정보와 수행 할 수 있는 행동에 대해 개략적으로 서술
- 객체의 책임은 크게 하는것과 아는것으로 나뉨
하는 것
- 객체를 생성하거나 계산을 수행하는 등의 스스로 하는 것
- 다른 객체의 행동을 시작시키는 것
- 다른 객체의 활동을 제어하고 조절하는 것
아는 것
- 사적인 정보에 관해 아는 것
- 관련된 객체에 관해 아는 것
- 자신이 유도하거나 계산할 수 있는 것에 관해 아는 것
- Screening은 협력 안에서 영화를 예매할 책임이 있기 때문에 reserve 메세지를 수신하고 movie를 인스턴스 변수로 갖는다.
- Movie는 가격 계산 책임을 가졌기 때문에 calculateMovieFee 메세지를 수신하고 fee와 discountPolicy를 변수로 갖는다.
- 이처럼 협력 안에서의 객체의 책임이 외부의 인터페이스와 내부의 속성을 결정한다.
3.2.2 책임 주도 설계
- 책임 주도 설계 : 책임을 찾고 책임을 수행할 적절한 객체를 찾아 책임을 할당하는 방식으로 협력을 설계하는 방법
- 책임 주도 설계는 객체의 구현이 아닌 책임에 집중할 수 있게 한다.
- 책임을 할당할 때 고려할 두가지 요소는 아래와 같다.
- 메시지가 객체를 결정한다.
- 행동이 상태를 결정한다.
3.2.3 메시지가 객체를 결정한다
- 객체에게 책임을 할당하는 데 필요한 메시지를 먼저 식별하고 메시지를 처리할 객체를 나중에 선택했다는 것이 중요하다.
- 객체가 메시지를 선택하는 것이 아니라 메시지가 객체를 선택
장점
- 첫째, 객체가 최소한의 인터페이스를 가질 수있게 함
- 필요한 메시지가 식별될 때 까지 객체에 어떤 것도 추가하지 않음
- 꼭 필요한 크기의 퍼블릭 인터페이스를 가질 수 있다.
- 둘째, 객체는 충분히 추상적인 인터페이스를 가지게 됨
- 객체의 인터페이스는 무엇을 수행하는지 표현할 뿐 어떻게 수행하는지는 노출해선 안된다.
- 메시지를 먼저 식별하면 무엇을 수행할지에 초첨을 맞출 수 있다.
3.2.4 행동이 상태를 결정한다
- 객체 지향 패러다임에서 쉽게 빠지는 실수는 객체의 행동이 아니라 상태에 초점을 맞추는 것이다.
- 객체에 필요한 상태가 무엇인지 결정하고 상태에 필요한 행동을 결정하는 것은 객체의 내부 구현이 퍼블릭 인터페이스에 노출되게 하므로 캡슐화를 저해한다.
- 객체의 내부 구현을 변경하면 퍼블릭 인터페이스도 변경되고, 결국 변경은 전파된다.
- 캡슐화를 위반하지 않도록 구현에 대한 결정을 뒤로 미루고 객체의 행위를 고려하자.
- 무엇을 제공하고 무엇을 얻어야 하는가를 고민하자
- 상태는 단지 객체가 행동을 정상적으로 수행하기 위해 필요한 재료일 뿐이다.
3.3 역할
3.3.1 역할과 협력
- 협력을 모델링 할때는 특정한 객체가 아니라 역할에게 책임을 할당한다고 생각해야 한다
- 영화 예매 협력에서 예매하라라는 메세지를 처리하기 위해서는
- 첫째, 영화를 예매할 수 있는 적절한 역할이 무엇인가를 찾는 것이고
- 둘째, 역학을 수행할 객체로 Screening 인스턴스를 선택하는 것이다.
3.3.2 유연하고 재사용 가능한 협력
- 역할이 중요한 이유는 역할을 통해 유연하고 재사용 가능한 협력을 얻을 수 있기 때문
- 같은 역할을 하는 여러 객체를 교대로 바꿔 끼울 수 있다.
- 역할은 구체적인 객체를 포괄하는 추상화된 상태다.
3.3.3 객체 대 역할
- 역할을 객체가 참여할 수 있는 일종의 슬롯
- 협력에 참여하는 후보가 여러 종류의 객체에 의해 수행될 필요가 있다면 역할, 단 한종류의 객체만 협력에 참여한다면 객체가 된다.
- 다양한 객체들이 협력에 참여한다는 것이 확실하다면 역할로 시작
- 모든것이 불분명하다면 구체적인 객체로 시작
3.3.4 역할과 추상화
- 추상화 계층만을 이용하면 중요한 정책을 상위 수준에서 단순화할 수 있다.
- 추상화를 사용하면 설계가 좀 더 유연해진다.
- 역할은 객체를 추상화하는것이므로, 추상화의 두 장점이 역할에도 동일하게 적용된다.
- 추상화의 첫 번째 장점은 세부사항에 억눌리지 않고도 상위 수준의 정책을 쉽고 간단하게 표현
- 협력이라는 관점에서는 세부적인 사항을 무시하고 추상화에 집중하는 것이 유용
728x90
반응형
'스터디 > 오브젝트' 카테고리의 다른 글
오브젝트 06 - 메시지와 인터페이스 (0) | 2024.02.26 |
---|---|
오브젝트 05 - 책임 할당하기 (0) | 2024.02.20 |
오브젝트 04 - 설계 품질과 트레이드오프 (0) | 2024.02.19 |
오브젝트 02 - 객체지향 프로그래밍 (0) | 2024.02.06 |
오브젝트 01 - 객체, 설계 (0) | 2024.02.06 |
댓글