책임 주도 설계

데이터 중심 설계는 객체의 구현이 이미 결정된 상태에서 협력을 고민하기 때문에 인터페이스에 구현이 노출된다.
데이터 중심 설계에서 책임 중심 설계로 전환하기 위해 다음 두 가지 원칙을 따라야 한다.

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

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

협력을 시작하는 주체는 메시지 전송자 이기 때문에 클라이언트의 의도에
적합한 책임을 할당해야 한다. 메세지를 결정한 후에 객체를 선택해야 한다.

2. GRASP 패턴

2-1) 도메인 개념에서 출발하기

설계를 시작하기 전에 도메인에 대한 개력적인 모습을 그려본다. FT_2021-04-02 02_44_27 585

2-2) 정보 전문가에게 책임을 할당하라

어플리케이션이 제공해야하는 기능을 어플리케이션의 책임으로 생각한다. 이 책임을 메세지로 간주하고 이 메세지를 책임질 첫번째 개체를 선택하는 것으로 설계를 시작한다.
첫 번째 질문 메세지를 전송할 객체는 무엇을 원하는가?
두 번째 질문 메세지를 수신할 적합한 객체는 누구인가?
책임을 수행할 정보를 알고 있는 객체에게 책임을 할당한다. 메세지를 수신했을 때 수행햐아 하는 작업의 흐름을 생각해본다.
다음 객체 내부로 들어가 메세지를 처리하기 위해 필요한 절차와 구현을 고민해 본다.
스스로 처리할 수 없는 작업은 외부에 도움을 요청한다. 이 메세지가 새로운 객체의 책임이 되고 메세지 전송과 수신을 통해 협력 공동체가 구성된다. FT_2021-04-02 02_53_58 838

2-3) 창조자에게 객체 생성 책임을 할당하라

객체A를 생성해야 할 때 아래 조건을 최대한 많이 만족하는 객체 B에 객체 생성 책임을 할당한다.

  • B 가 A 를 포함하거나 참조한다.
  • B 가 A 를 기록한다.
  • B 가 A 를 긴밀하게 사용한다.
  • B 가 A 를 초기화 하는데 필요한 데이테를 가지고 있다.

2-4) 데이터 결정

FT_2021-04-02 03_02_18 595

3. 구현을 통한 검증

3-1) 클래스 분리

변경의 이유에 따라 클래스를 분리한다.

  • 인스턴스 변수가 초기화 되는 시점이 다르면, 함께 초기화 되는 속성을 기준으로 코드를 분리한다.
  • 메서드들이 사용하는 속성에 따라 그룹이 나뉜다면 그룹을 기준으로 코드를 분리한다.

3-2) 다형성을 통해 분리하기

객체의 타입에 따라 조건적인 논리를 사용하는 로직이 있으면 다형성을 이용해 타입을 분리한다.
한 클래스에 다른 변경의 이유가 함께 있다면, 변경에 따라 분리하고 인터페이스로 변경을 캡슐화 한다.

3-3) 상속과 합성

클래스를 분리하고 구현을 공유할 필요가 있으면 추상 클래스를 사용한다.
변경에 유연한 코드를 위해 상속 대신 합성을 사용이 가능한지 고려한다.