책임주도설계(Responsibility Driven Design)

쉽게 말해 책임을 어디에 배치하는가. 책임을 수행할 수 있는 적절한 객체를 찾아 할당하고, 책임을 수행하는 도중 다른 객체의 도움이 필요한 경우 메시지를 수신할 객체를 찾아 책임을 할당한다. 해당 객체에 책임을 할당함으로써 두 객체가 협력하게 된다.(반복 134page 참고)


책임주도설계 원칙

  • 데이터보다 행동을 먼저 결정하라. (78page에서 무엇을 할지) 즉 행동은 책임.
  • 협력이라는 문맥 안에서 책임을 결정하라.

책임을 먼저 결정하고, 객체를 결정.
책임이 조금 어색해 보이더라도 협력에 적합하다면 그 책임은 좋은것이다.


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

객체 설계와 책임 할당에 관한 기본적인 원리를 패턴형식에 맞추어 기술한 것. (패턴이라는 것은 가이드일뿐 원칙이 아님. 하면 좋고 안하면…나쁘지만 안되는건 아님)


5-GRASP 패턴

  • 정보 전문가 패턴
  • 생성자 패턴
  • 높은 응짐도 패턴
  • 낮은 결합도 패턴
  • 컨트롤러 패턴

추가 GRASP 패턴

  • 다형성 패턴
  • 순수 가공 패턴
  • 간접 패턴
  • 보호변형 패턴

도메인개념에서 시작하라

  • 도메인 개념에서 설계를 시작하라는 것이지 도메인 개념들을 완벽하게 정리하라는 것이 아니다.
  • 필요한것은 도메인을 그대로 투영한 모델이 아니라 구현에 도움이 되는 모델
  • 도메인 모델에는 도메인 안에서 예측 가능한 변경에 대한 직관이 반영돼 있어야한다.

정보 전문가(Information Expert)

객체의 책임과 책임을 수행하는데 필요한 상태는 객체 안에 존재해야 한다.(객체는 자신의 상태를 스스로 처리하는 자율적인 존재)


문제 누가 책임을 수행하는가?

해결 책임에 대한 정모를 많이 가지고 있는 객체가 수행한다.

정보는 데이터와 다르다. 책임을 수행하는 객체가 정보를 알고 있다고 해서 그 정보를 저장 하고 있을 필요는 없다. 필요한 정보를 계산해서 제공할 수도 있다.


LOW COUPLING(낮은 결합도)

한 객체가 다른 객체와 얼마나 연관 되었는가에 대한 척도. 하나의 객체는 다른 객체의 정보가 최대한 적어야한다.(단방향 의존성)


예) ScreeningDiscountCondition 사이에 없던 새로운 결합도가 추가된다. MovieDiscountCondition사이는 이미 결합되어있다.

그런데 Movie와의 결합은 Screening과 결합 하면 사라지는게 아닌지? 143


HIGH COHESION(높은 응집도)

하나의 객체는 하나의 이유로 변형되어야함.


예) Screening의 주된 책임은 예매를 생성하는것. DiscountCondition 가 결합되면 Screening이 변경되는 다른 이유가 생긴다. 즉 응집도가 낮아짐을 뜻함. 반면 Movie의 주된 책임은 요금 계산으로 DiscountCondition과의 협력이 응집도에 아무런 해가 되지 않는다.

응집도 판단하기

  • 클래스가 하나 이상의 이유로 변경돼야 한다면 응집도가 낮은것.
  • 클래스의 인스턴스 변수를 초기화하는 시점이 다른 경우 응집도가 낮은것.
  • 메스드들이 사용하는 속서에 따라 그룹이 나뉜다면 응집도가 낮은것.

예) DiscountCondition


CREATER(생성자) 패턴

객체를 생성할 책임을 어떤 객체에 할당할지에 대한 지침.


문제 누가 객체 A를 생성하는가?

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

  • B가 A객체를 포함하거나 참조한다.
  • B가 A객체를 기록한다.
  • B가 A객체를 긴밀하게 사용한다.
  • B가 A객체를 초기화 하는데 필요한 데이터를 가지고 있다.(B는 A에 대한 정보전문가)

예) Screening은 예매를 생성하는데 필요한 정보를 가지고 있다. 따라서 Reservation의 생성자로 적절하다.


POLYMORPHISM(다형성) 패턴

타입을 명시적으로 정의하고 각타입에 다형적으로 행동하는 책임을 할당. 프로그램을 조건문을 사용해 설계한다면 새로운 변화가 일어난 경우 조건문을 수정해야한다. 이는 프로그램을 수정하기 어렵고 변경에 취약하게 만든다. 대신 다형성을 이용해 새로운 변화를 다루기 쉽게 확장하자. 159


PROTECTED VATIATIONS(변경 보호) 패턴

책임할당의 관접에서 캡슐화를 설명한것. 예측가능한 변경으로 인해 여러 클래스들이 불안정해진다면, 변경보호 패턴을 통해 안정적인 인터페이스 뒤로 변경을 캡슐화하자.(쉽게 말해 추상화 하라는 뜻)


예) DiscountCondition이라는 추상화가 구체적인 타입을 캡슐화한다. 새로운 DiscountCondition을 추가해도 Movie는 영향을 받지 않는다. 이처럼 변경을 캡슐화하도록 책임을 할당하는 것을 PROTECTED VATIATIONS(변경 보호) 패턴이라고 부른다.


CONTROLLER(컨트롤러) 패턴

요청을 처리할 객체를 만들자. 직접적으로 객체간 요청을 하게 된다면 결합도가 증가한다.


INDIRECTION(간접) 패턴

두 객체 사이에 직접적인 결합을 피하고 싶다면, 그사이에 다른 객체를 사용하자. (인터페이스나 추상클래스 등) 인터페이스 인경우 변경 보호 패턴이라고 부를 수 있다.


PURE FABRICATION(순수 가공)

공통기능을 한곳에 모으자.


결론

  • 위에 설명한 방법들로 코드를 잘 격리하자.
  • 코드를 격리시켜 변경을 수용하기 쉽게 혹은 수정하기 쉽게 만들자. 설계를 주도하는것은 변경이다.

참고