해당 챕터에서는 객체지향 패러다임의 핵심 3가지에 대해 이야기하고 있다.
서론
객체지향 패러다임의 핵심은 다음과 같다.
- 역할 (role)
- 책임 (responsibility)
- 협력 (collaboration)
객체들의 책임과 협력이 어느 정도 자리 잡은 후 사용할 수 있는 구현 메커니즘
- 클래스
- 상속
객체지향 설계의 핵심은 협력을 구성하기 위해 적절한 객체를 찾고 적절한 책임을 할당하는 과정에서 발생한다.
나는 다음과 같은 구절이 정말 나에게 많이 와닿았다.
"애플리케이션의 기능을 구현하기 위해 어떤 협력이 필요하고 협력을 위해 어떤 역할과 책임이 필요한지를 고민하지 않은 채 너무 이른 시기에 구현에 초점을 맞추는 것은 변경하기 어렵고 유연하지 못한 코드를 낳는 원인이 된다 "
맞다. 진행했던 프로젝트를 찬찬히 살펴보았을 때, 충분한 시간적 여유가 있음에도 불구하고 혼자 급하게 진행을 하였을 때 내가 생각했던 방향과 달라 기존의 로직을 뜯어고쳤던 기억이 있다.
해당 경험을 토대로, 요즘은 종이를 두고 다음과 같이 고민을하며 시작한다.
- 어떻게 시작할지?
- 어떻게 나눌지 ?
상황별을 쭉 나열해 놓고 하나씩 퍼즐처럼 맞춰가면서 진행한 후에 개발을 시작하려고 노력하고 있다.
다시 내용으로 돌아와 보자
해당 내용의 핵심은 다음과 같다고 이야기하고 있다.
역할, 책임, 협력이 제자리를 찾지 못한 상태라면 응집도 높은 클래스와 중복 없는 상속 계층을 구현한다 하더라도 무조건 침몰한다.
협력
해당 챕터에서는 이전에 실습한 영화 예매 시스템을 토대로 이야기를 하였다.
해당 플로우 차트를 살펴봤을 때 나는 다음과 같이 생각하였고, 책에서도 다음과 같이 이야기하고 있었다.
- 다양한 객체들이 영화 예매라는 기능을 구현하기 위해 메시지를 주고받으면서 상호작용한다.
해당 내용을 이야기하며, 책에서는 협력, 책임, 역할을 다음과 같이 정의하였다.
협력
- 애플리케이션의 기능을 구현하기 위해 수행하는 상호작용
책임
- 객체가 협력에 참여하기 위해 수행하는 로직
역할
- 객체들이 협력 안에서 수행하는 책임들이 모여 객체가 수행
그럼, 각각의 정의를 살펴보았으니 이 3가지의 내용을 더 살펴보도록 해보자
협력은 어떤 객체가 다른 객체에게 무엇인가를 요청하는 것이다.
각 객체는 메시지를 처리할 방법을 스스로 선택해야 한다 즉, 자율적인 존재라는 것을 의미한다.
다음은 예매 요금을 계산하기 위한 협력관계를 나타낸 것이다.
위에서 말한 것과 같이 calculateMovieFee라는 메시지를 통해 요금 게산을 진행한다.
해당 부분을 통해 알 수 있듯, Screening과 Movie는 메시지를 통해 협력하고 있는 관계임을 확인할 수 있다.
요금계산을 Movie에 위임하는 이유는 할인 정책 및 기본요금의 대한 데이터를 가장 잘 알고 있는 게 Movie 객체이기 때문이다.
해당 부분처럼 진행할 경우, Screening이 Movie의 객체의 데이터를 받아 진행하기에, 이는 별도의 객체로 나뉘는 문제점이 발생하고
Movie는 자율적인 존재가 아닌 수동적인 존재로 전락해버리고 만다.
그렇다면 어떻게 해야 할까?
책에서도 내용이 나와있지만 간단하다. 요금계산의 경우 해당 데이터를 가지고 있는 Movie에서 직접 구현을 하면 된다.
이는 이전에 이야기한 캡슐화와도 관련이 있는데 이렇게 되면 결과적으로 Movie는 영향을 받지 않고 결과를 제공할 수 있게 되고
Screening과 Movie사이의 결합도 또한 느슨하게 바꿀 수 있다는 장점을 가지고 있다.
다음과 같은 기법을 TDA ( Tell Don't Ask ) 기법이라고 한다.
이에 대한 예제를 한번 이야기해보겠다. 해당 예제는 사수분이 제공해준 내용이다.
우리가 만약 어떠한 가게에 들어가 물건을 구입한다고 가정을 해보겠다.
물건을 고른 후, 우리가 계산을 할 때 우리는 지갑에 있는 돈을 전부 꺼내는 것이 아닌 물건의 액수만 꺼내 전달할 것이다.
위와 같이, 해달라라고 하는 것이 아닌 해줘.라는게 해당 내용의 핵심이라고 할 수 있다.
해당 내용을 읽었을 때 협력의 핵심은 자율적인 객체를 만들어 서로의 결합도를 느슨하게 하는것이 핵심이 아닐까 싶었다.
협력이 설계를 위한 문맥을 제공한다.
객체지향은 객체를 중심에 놓는 프로그래밍 패러다임이다.
애플리케이션 안에 객체가 필요하다면 그 이유는 객체가 어떤 협력에 참여하고 있기 때문이다.
객체가 협력에 참여할 수 있는 이유는 협력에 필요한 적절한 행동을 보유하고 있기 때문이다.
결론적으로 객체의 행동을 결정하는 것은 객체가 참여하고 있는 협력이다.
상태는 객체가 행동하는 데 필요한 정보에 의해 결정된다.
행동은 협력 안에서 객체가 처리할 메시지로 결정된다.
결과적으로 객체가 참여하는 협력이 객체를 구성하는 행동과 상태 모두를 결정하게 된다.
따라서 협력은 객체를 설계하는 데 필요한 일종의 문맥( context )을 제공한다.
책임
- 협력에 참여하기 위해 객체가 수행하는 행위
해당 부분은 하는 것(doing)과아는 것(knowing) 나눠 이야기하고 있다.
하는 것
- 객체를 생성하거나 계산을 수행하는 등의 스스로 하는 것
- 다른 객체의 행동을 시작하는 것
- 다른 객체의 활동을 제어하고 조절하는 것
아는 것
- 사적인 정보에 관해 아는 것
- 관련된 객체에 관해 아는 것
- 자신이 유도하거나 계산할 수 있는 것에 관해 아는 것
책임은 객체지향의 핵심이라고 이야기할 수 있다.
이에 대해 크레이그 라만은 다음과 같이 이야기를 하고 있다.
"객체지향 개발에서 가장 중요한 능력은 책임을 능숙하게 소프트웨어 객체에 할당하는 것"
해당 각 객체들에게 책임을 부여할 때는 필요한 정보를 가장 잘 알고 있는 객체에게 책임을 부여하는 것이 핵심이다.
아까의 예시를 생각해 봤을 때, 영화를 예매하고자 하였을 때 Movie 객체가 해당 영화의 가격 및 할인 정책에 대해 더 잘 알고 있지 않았는가?
이때 Movie라는 객체에게 예매의 책임을 할당할 수 있다는 것으로 엮어서 생각해볼 수 있었다.
이를 책임 할당을 위한 정보 전문가(INFORMATION EXPERT)라고도 한다.
책임 주도 설계 ( Reponsibility-Driven Design, RDD )
- 책임을 찾고 책임을 수행할 적절한 객체를 찾아 책임을 할당하는 방식으로 설계하는 방법
이전까지 예제로서 살펴본 내용이 책임 주도 설계 방법에서 제시하는 기본적인 흐름을 따른 것이다.
책임 주도 설계 방법을 설계하기 위한 방법의 과정은 다음과 같다.
- 시스템이 사용자에게 제공해야 하는 기능인 시스템 책임을 파악한다.
- 시스템 책임을 더 작은 책임으로 분할한다.
- 분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당한다.
- 객체가 책임을 수행하는 도중 다른 객체의 도움이 필요한 경우 이를 책임질 적절한 객체 또는 역할을 찾는다.
- 해당 객체 또는 역할에게 책임을 할당함으로써 두 객체가 협력하게 된다.
객체의 행동은 객체가 협력할 수 있는 유일한 방법이라고 할 수 있다.
레베카 워프스브록은 객체의 내부 구현에 초점을 맞춘 설계 방법을 데이터 주도 설계 (Data-Driven Design)이라고 하였다.
여기까지 살펴보았을 때, 객체는 "행동"을 통해 상태를 결정 즉, 행동이 매우 중요함을 알 수 있었다.
역할
나는 해당 내용을 읽을 때 이전, 인프런 김영한 님의 스프링 강의를 들었을 때가 마구 떠올랐다.
그때 로미오와 줄리엣을 예시를 들어 설명을 해주셨었는데, 핵심은 어떠한 출연자가 와도 해당 배역의 역할은 절대 바뀌지 않는다.
즉, 본질적인 역할은 변하지 않는 게 핵심이다.
즉, 교체에 유연성을 가지고 있어야 하는 게 핵심이다. 이때 사용할 수 있는 건 추상 클래스와 인터페이스를 사용할 수 있을 것이다.
협력에 적합한 책임을 수행하는 대상이 한 종류라면 객체
여러 종류의 객체들이 참여할 수 있다면 역할
다음과 같이 나눌 수 있다.
결론
위 3가지의 내용을 살펴보았지만 이중 제일 중요한 건 객체의 책임이다.
책에서도 이야기하고 매우 강조하고 있고, 나 또한 해당 객체의 책임을 어떻게 나누는가? 이게 핵심으로 보였다.
항상 프로젝트를 진행할 때와 구현을 할때 해당 책임을 어떻게 할지 고민했던 내 모습이 떠올랐고 어느 정도 내가 잘못 생각한 게 아니었구나 생각이 들었다.
'BOOK' 카테고리의 다른 글
[BOOK: 오브젝트 5장] 책임 할당하기 (0) | 2022.11.05 |
---|---|
[BOOK : 오브젝트 4장] 설계 품질과 트레이드 오프 (0) | 2022.10.30 |
[BOOK : 클린코드 1장] 깨끗한 코드 (0) | 2022.10.23 |
[BOOK : 오브젝트 2장] 객체지향 프로그래밍을 읽고 (0) | 2022.10.21 |
[BOOK : 오브젝트 1장] 객체, 설계를 읽고 (0) | 2022.10.20 |