새소식

반응형
Study/오브젝트

[Object] 5장 : 책임 할당하기

  • -
반응형

책임에 초점을 맞춰 설계할 때 직면하는 가장 큰 문제는 어떤 객체에게 어떤 책임을 할당할지를 결정하기 어렵다는 점이다.

책임 할당 과정은 일종의 트레이트오프 활동이다.

책임 주도 설계를 향해

데이터 중심의 설계에서 책임 중심의 설계로 전환하기 위한 원칙 

  • 데이터보다 행동을 먼저 결정하라 
    • 데이터는 객체가 책임을 수행하는 데 필요한 재료를 제공할 뿐이다.
    • 객체를 설계하기 위한 질문의 순서를 바꾸자.
      • 데이터 중심의 설계 : "이 객체가 포함해야 하는 데이터가 무엇인가" -> "데이터를 처리하는 데 필요한 오퍼레이션은 무엇인가"
      • 책임 중심의 설계 : "이 객체가 수행해야 하는 책임은 무엇인가" -> "이 책임을 수행하는 데 필요한 데이터는 무엇인가"
  • 협력이라는 문맥 안에서 책임을 결정하라
    • 적합한 책임이란 메시지 수신자가 아니라 메시지 전송자에게 적합한 책임을 의미한다. 
      즉, 메시지를 전송하는 클라이언트의 의도에 적합한 책임을 할당해야 한다.
    • 객체를 가지고 있기 때문에 메시지를 보내는 것이 아니다.
      메시지를 전송하기 때문에 객체를 갖게 된 것이다.

책임 주도 설계

핵심은 책임을 결정한 후에 책임을 수행할 객체를 결정하는 것

협력에 참여하는 객체들의 책임이 어느 정도 정리될 때까지는 객체의 내부 상태에 대해 관심을 가지지 않는 것

  • 책임 주도 설계의 흐름
    • 시스템이 사용자에게 제공해야 하는 기능인 시스템 책임을 파악
    • 시스템 책임을 더 작은 책임으로 분할
    • 분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당
    • 다른 객체의 도움이 필요한 경우 이를 책임질 적절한 객체 또는 역할을 찾는다
    • 해당 객체 또는 역할에게 책임을 할당함으로써 두 객체가 협력하게 된다.

책임 할당을 위한 GRASP 패턴

GRASP (General Responsibility Assignment Software Pattern) (일반적인 책임 할당을 위한 소프트웨어 패턴)

객체에게 책임을 할당할 때 지침으로 삼을 수 있는 원칙들의 집합을 패턴 형식으로 정리한 것

  • 도메인 개념에서 출발하기 
    • 설계를 시작하기 전에 도메인에 대한 개략적인 모습을 그려 보는 것이 유용하다. -> 출발점으로 삼기 위해
  • 정보 전문가에게 책임을 할당하라 - Information Expert 
    • 객체에게 책임을 할당하는 첫 번째 원칙은 책임을 수행할 정보를 알고 있는 객체에게 책임을 할당하는 것이다. 
    • 객체가 정보를 '알고' 있다고 해서 그 정보를 '저장'하고 있을 필요는 없다.
       -> '정보' 전문가에서 '정보'는 '데이터'와 다르다. 
    • 스스로 처리할 수 없는 작업이 있다면 외부에 도움을 요청해야 한다
  • 높은 응집도와 낮은 결합도 - High Cohesion & Low Coupling
    • Low Coupling : 설계의 전체적인 결합도가 낮게 유지되도록 책임을 할당하라.
    • High Cohesion : 높은 응집도를 유지할 수 있게 책임을 할당하라
    • 책임과 협력의 품질을 검토하는 데 사용할 수 있는 중요한 평가 기준 
  • 창조자에게 객체 생성 책임을 할당하라 - Creator
    • 객체를 생성할 책임을 어떤 객체에게 할당할지에 대한 지침
    • 객체 A를 생성해야 할 때 이하 조건을 최대한 많이 만족하는 B에게 객체 생성 책임을 할당하라.
      • B가 A 객체를 포함하거나 참조한다.
      • B가 A 객체를 기록한다.
      • B가 A 객체를 긴밀하게 사용한다.
      • B가 A 객체를 초기화하는 데 필요한 데이터를 가지고 있다(이 경우 B는 A에 대한 정보 전문가다)

협력과 책임이 제대로 동작하는지 확인할 수 있는 유일한 방법은 코드를 작성하고 실행해 보는 것뿐이다. 

올바르게 설계하고 있는지 궁금한가?  코드를 작성하라.

구현을 통한 검증

  • 다형성을 통해 분리하기 - Polymorphism 
    • 객체의 타입에 따라 변하는 행동이 있다면 타입을 분리하고 변화하는 행동을 각 타입의 책임으로 할당하라 (역할) 
  • 변경으로부터 보호하기 - Protected Variations 
    • 변경을 캡슐화하도록 책임을 할당하는 것 

설계를 주도하는 것은 변경이다.

  • 코드를 이해하고 수정하기 쉽도록 최대한 단순하게 설계
  • 코드를 수정하지 않고도 변경을 수용할 수 있도록 코드를 더 유연하게 만드는 것

대부분의 경우 '1'이 더 좋은 방법이지만

유사한 변경이 반복적으로 발생하고 있다면 복잡성이 상승하더라도 유연성을 추가하는 '2'의 방법이 더 좋다.

책임 주도 설계의 대안

설계가 어려울 때 실행되는 코드를 얻고 난 후에 

코드 상에 드러나는 명확한 책임들을 올바른 위치로 이동시키는 방법을 사용한다.

  • 리팩터링 
    • 캡슐화를 향상시키고, 응집도를 높이고, 결합도는 낮추는 작업 
    • 동작은 바뀌지 말아야 한다. 
  • 메서드 응집도 
    • 긴 메서드 
      • 파악하기 어려움 
      • 수정 어려움 
      • 일부 로직 변경 시 버그 발생 위험 높음 
      • 로직 재사용이 불가능 
      • 코드 중복 
    • 짧은 메서드 
      • 재사용의 가능성이 높아진다
      • 일련의 주석을 읽는 것 같은 느낌이 든다

객체를 자율적으로 만들자 

메서드를 다른 클래스로 이동시킬 때는 인자에 정의된 클래스 중 하나로 이동하는 경우가 일반적이다. 

  • 데이터를 사용하는 메서드를 데이터를 가진 클래스로 이동시키면
  • 캡슐화, 높은 응집도, 낮은 결합도를 가지는 설계를 얻는다
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.