본문 바로가기
스터디/오브젝트

5장 - 책임 할당하기

by 검은도자기 2023. 4. 10.

개요

이번 장에서는 책임을 할당하는 기준과 책임 중심 설계를 어떻게 하면 되는지에 대해 다룹니다.

 

 

데이터 중심 설계의 문제점을 해결할 수 있는 방법은 무엇일까?

  • 가장 기본적인 방법은 데이터가 아닌 책임에 초점을 맞추는 것입니다.

 

어떻게 책임을 할당할까?

책임 중심의 설계를 하기 위해서는 다음의 두 가지 원칙을 따라야 합니다.

 

  1. 데이터보다 행동을 먼저 결정하라
  2. 협력이라는 문맥 안에서 책임을 결정하라

 

데이터보다 행동을 먼저 결정하라

  • 객체에게 중요한 것은 데이터가 아니라 외부에 제공하는 행동입니다.
  • 객체에게 데이터는 객체가 책임을 수행하는 데 필요한 재료를 제공할 뿐입니다.
  • 너무 이른 시기에 데이터에 초점을 맞추면 객체의 캡슐화가 약화되기 때문에 낮은 응집도와 높은 결합도를 가진 객체들로 넘쳐나게 되며, 그 결과로 얻게 되는 것은 변경에 취약한 설계입니다.
  • 따라서 우리에게 필요한 것은 객체의 데이터에서 행동으로 무게 중심을 옮기기 위한 기법입니다.

 

행동으로 무게 중심을 옮기기 위한 방법은 무엇일까?

  • 행동으로 무게 중심을 옮기기 위한 기본적인 방법은 아래 질문 순서대로 고민하면서 결정해야 합니다.
    • 이 객체가 수행해야 하는 책임은 무엇인가?
    • 이 책임을 수행하는 데 필요한 데이터는 무엇인가?
  • 책임 중심의 설계에서는 객체의 행동, 즉 책임을 먼저 결정한 후에 객체의 상태를 결정합니다.
  • 위 사실을 봤을 때 "객체에게 어떤 책임을 할당해야 할까?"라는 질문의 해결책은 협력에서 찾을 수 있습니다.

 

협력이라는 문맥 안에서 책임을 결정하라

  • 객체에게 할당된 책임의 품질은 객체가 참여하는 협력에 적합한 정도로 결정되며, 이 사실은 객체의 책임을 어떻게 식별해야 하는가에 대한 힌트를 제공합니다.
  • 협력을 시작하는 주체는 메시지 전송자이기 때문에 메시지를 전송하는 클라이언트의 의도에 적합한 책임을 할당해야 합니다.
  • 따라서 협력에 적합한 책임을 수확하기 위해서는 메시지를 결정한 후에 객체를 선택해야 합니다.
  • 메시지가 존재하기 때문에 그 메시지를 처리할 객체가 필요한 것이며 객체가 메시지를 선택하는 것이 아니라 메시지가 객체를 선택하게 해야 합니다.

 

메시지는 어떻게 결정해야 할까?

  • "메시지를 전송해야 하는데 누구에게 전송해야지?"라는 질문을 스스로에게 던지면서 고민한 뒤 결정해야 합니다.

 

메시지 관점으로 설계하면 어떤 부분이 좋은 걸까?

  • 클라이언트는 어떤 객체가 메시지를 받을지 알지 못하며 임의의 객체가 메시지를 수신할 것이라는 사실을 믿고 자신의 의도를 표현한 메시지를 전송합니다.
  • 메시지를 먼저 결정하기 때문에 메시지 송신자는 메시지 수신자에 대한 어떤 가정도 할 수 없습니다.
  • 메시지 전송자의 관점에서 메시지 수신자가 깔끔하게 캡슐화되는 것입니다.
  • 이처럼 처음부터 데이터에 집중하는 데이터 중심의 설계가 캡슐화에 취약한 반면 협력이라는 문맥 안에서 메시지에 집중하는 책임 중심의 설계는 캡슐화의 원리를 지키기가 훨씬 쉬워집니다.
  • 책임 줌심의 설계가 응집도가 높고 결합도가 낮으며 변경하기 쉽다고 말하는 이유가 여기에 있습니다.

 

그래서 책임 주도 설계를 어떻게 해야 할까?

  • 책에서 제공하는 영화 예매 시스템 설계 예시를 보면서 어떻게 설계를 해야 할지 고민해 봅니다.

 

도메인 개념에서 출발하기

  • 어떤 책임을 할당해야 할 때 가장 먼저 고민해야 하는 유력한 후보는 바로 도메인 개념입니다.
  • 이 단계에서는 책임을 할당받을 객체들의 종류와 관계에 대한 유용한 정보를 제공할 수 있다면 충분합니다.
  • 중요한 것은 설계를 시작하는 것이지 도메인 개념들을 완벽하게 정리하는 것이 아닙니다.
  • 도메인 개념을 정리하는 데 너무 많은 시간을 들이지 말고 빠르게 설계와 구현을 진행해야 합니다.
  • 영화 예매 시스템에서 사용자에게 제공해야 하는 기능은 영화를 예매하는 것입니다.
  • 따라서 첫 번째 질문은 다음과 같습니다.

 

 

 

메시지를 전송할 객체는 무엇을 원하는가?

  • 제일 먼저 책임을 수행하는 데 필요한 메시지를 결정해야 합니다.
  • 메시지는 메시지를 수신할 객체가 아니라 메시지를 전송할 객체의 의도를 반영해서 결정해야 합니다.
  • 협력을 시작하는 객체는 미정이지만 이 객체가 원하는 것 영화를 예매하는 것입니다.
  • 메시지 이름으로는 예매하라가 적절한 것 같습니다.
  • 메시지를 결정했으므로 메시지에 적합한 객체를 선택해야 합니다.
  • 따라서 두 번째 질문은 다음과 같습니다.

 

메시지를 수신할 적합한 객체는 누구인가?

 

  • 위 질문에 답하기 위해서는 객체가 상태와 행동을 통합한 캡슐화의 단위라는 사실에 집중해야 합니다.
  • 객체의 책임과 책임을 수행하는 데 필요한 상태는 동일한 객체 안에 존재해야 합니다.
  • 따라서 객체에게 책임을 할당하는 첫 번째 원칙은 책임을 수행할 정보를 알고 있는 객체에게 책임을 할당하는 것이며, 이를 Informatin Expert(정보 전문가) 패턴이라고 부릅니다.
  • Informatin Expert(정보 전문가) 패턴에 따르면 예매하는 데 필요한 정보를 가장 많이 알고 있는 객체에게 메시지를 처리할 책임을 할당해야 합니다.
  • 여기에서는 상영이라는 도메인 개념이 적합합니다.
  • 왜냐하면 상영은 영화에 대한 정보, 상영 시간, 상영 순번처럼 영화 예매에 필요한 다양한 정보를 알고 있기 때문입니다.

 

  • 다음은 예매하라 메시지를 수신했을 때 Screening이 수행해야 하는 작업의 흐름을 생각해 봅니다.
  • 이제부터는 외부의 인터페이스가 아닌 Screening의 내부로 들어가 메시지를 처리하기 위해 필요한 절차와 구현을 고민해 보는 것입니다.
  • 세세하게 고민하지 말고 책임을 수행하는 데 필요한 작업을 구상하고 스스로 처리할 수 없는 작업이 무엇인지를 가릴 정도의 수준이면 됩니다.
  • 만약 스스로 처리할 수 없는 작업이 있다면 외부에 도움을 요청해야 합니다.
  • 이 요청이 외부로 전송해야 하는 새로운 메시지가 되고, 최종적으로 이 메시지가 새로운 객체의 책임으로 할당됩니다.
  • 이 같은 연쇄적인 메시지 전송과 수신을 통해 협력 공동체가 구성되는 것입니다.

 

  • 예매하라 메시지를 완료하기 위해서는 예매 가격을 계산하는 작업이 필요합니다.
  • 예매 가격은 영화 한 편의 가격을 계산한 금액에 예매 인원수를 곱한 값으로 구할 수 있습니다.
  • 따라서 영화 한 편의 가격을 알아야 합니다.
  • 가격을 계산하는데 필요한 정보를 모르기 때문에 외부의 객체에게 도움을 요청해서 가격을 얻어야 합니다.
  • 외부에 대한 이 요청이 새로운 메시지가 됩니다.
  • 여기서 새로운 메시지의 이름으로는 가격을 계산하라가 적절할 것입니다.

 

  • 이제 메시지를 책임질 객체를 선택해야 합니다.
  • 기본 원칙은 정보 전문가에게 책임을 할당하는 것입니다.
  • 여기에서 영화 가격을 계산하는 데 필요한 정보를 알고 있는 전문가는 영화입니다.
  • 따라서 Movie는 영화 가격을 계산할 책임을 지게 됩니다.

 

  • 이제 가격을 계산하기 위해 Movie가 어떤 작업을 해야 하는지 생각해야 합니다.
  • 요금을 계산하기 위해서는 먼저 영화가 할인 가능한지를 판단한 후 할인 정책에 따라 할인 요금을 제외한 금액을 계산하면 됩니다.
  • 이 중에서 영화가 스스로 처리할 수 없는 일이 한 가지 있습니다.
  • 그건 할인 조건에 따라 영화가 할인 가능한지를 판단하는 것입니다.
  • 따라서 Moive는 할인 여부를 판단하라 메시지를 전송해서 외부의 도움을 요청해야 합니다.

 

  • 이제 메시지를 책임질 객체를 선택할 차례입니다.
  • 할인 여부를 판단하는 데 필요한 정보를 가장 많이 알고 있는 객체는 무엇인가?
  • 이 정보에 대한 전문가는 바로 할인 조건입니다.
  • 따라서 DiscountCondition에게 이 책임을 할당합니다.
  • DiscountCondition은 자체적으로 할인 여부를 판단하는 데 필요한 모든 정보를 알고 있기 때문에 외부의 도움 없이도 스스로 할인 여부를 판단할 수 있습니다.
  • 따라서 DiscountCondition은 외부에 메시지를 전송하지 않습니다.
  • Movie는 DiscountCondition에 전송한 할인 여부를 판단하라 메시지의 결과로 할인 가능 여부를 반환받습니다.
  • DiscountCondition 중에서 할인 가능한 조건이 하나라도 존재하면 금액 할인 정책이나 비율 할인 정책에 정해진 계산식에 따라 요금을 계산한 후 반환하며, 만약 할인 가능한 조건이 존재하지 않는다면 영화의 기본 금액을 반환합니다.

 

  • 영화 예매 협력의 최종 결과물은 Reservation 인스턴스를 생성하는 것입니다.
  • 이것은 어떤 객체에게는 Reservation 인스턴스를 생성할 책임을 할당해야 한다는 것을 의미합니다.
  • CREATOR(창조자) 패턴은 이 같은 경우에 사용할 수 있는 책임 할당 패턴으로서 생성할 책임을 어떤 객체에게 할당할지에 대한 지침을 제공합니다.
  • Reservation을 잘 알고 있거나, 긴밀하게 사용하거나, 초기화에 필요한 데이터를 가지고 있는 객체는 무엇일까?
  • 바로 Screening입니다.
  • 왜냐하면 Screening은 예매 정보를 생성하는 데 필요한 영화, 상영 시간, 상영 순번 등의 정보에 대한 전문가이며, 예매 요금을 계산하는 데 필수적인 Movie도 알고 있습니다.
  • 따라서 Screening을 Reservation의 CREATOR로 선택하는 것이 적절해 보입니다.
  • 대략적으로나마 영화 예매에 필요한 책임을 객체들에게 할당했습니다.

 

CREATOR(창조자) 패턴이란?

  • 객체를 생성할 책임을 어떤 객체에게 할당할지에 대한 지침을 제공하는 패턴입니다.
  • 이 패턴에서는 객체 A를 생성해야 할 때 어떤 객체에게 객체 생성 책임을 할당해야 하는가?라는 질문에 대한 답으로 아래 조건을 최대한 많이 만족하는 B에게 객체 생성 책임을 할당해야 한다고 말합니다.
    • B가 A 객체를 포함하거나 참조한다.
    • B가 A 객체를 기록한다.
    • B가 A 객체를 긴밀하게 사용한다.
    • B가 A 객체를 초기화하는 데 필요한 데이터를 가지고 있다.(이 경우 B는 A에 대한 정보 전문가입니다.)

 

 

마무리

오늘은 오브젝트 책 5장을 스터디하면서 중요하다고 생각한 부분을 정리해 보았습니다.

5장은 처음 읽고 난 뒤 중요하다고 생각이 들어서 2~3번 정도 반복해서 읽게 되었네요.

읽고 나니 책임 주도 설계를 어떤 관점, 기준으로 하면 될지 감이 잡히게 되어서 좋았던 장이었다고 생각이 듭니다.

이제 감이 잡혔으니 여러 번 설계를 진행해 보면서 몸에 체득화될 때까지 연습하면 되겠다고 생각이 드네요.

이번 포스팅은 마무리하면서 다음 포스팅에서 뵙겠습니다.

 

 

참고

http://www.yes24.com/Product/Goods/74219491

 

오브젝트 - YES24

역할, 책임, 협력을 향해 객체지향적으로 프로그래밍하라!객체지향으로 향하는 첫걸음은 클래스가 아니라 객체를 바라보는 것에서부터 시작한다. 객체지향으로 향하는 두번째 걸음은 객체를

www.yes24.com

 

'스터디 > 오브젝트' 카테고리의 다른 글

7장 - 객체 분해  (0) 2023.04.30
6장 - 메시지와 인터페이스  (0) 2023.04.17
4장 - 설계 품질과 트레이드오프  (0) 2023.03.28
3장 - 협력, 책임, 역할  (2) 2023.03.12
2장 - 협력, 객체, 클래스  (0) 2023.03.05