5장: 책임 할당하기
책임 주도 설계를 향해
데이터보다 행동을 먼저 결정하라
책임을 먼저 결정한 후에 객체의 상태를 결정한다.
협력이라는 문맥 안에서 책임을 결정하라
객체의 입장에서 책임이 조금 어색해 보이더라도 협력에 적합하다면 그 책임은 좋은 것이다.
메시지를 결정하고 누구에게 전송할 지 정한 후에 객체를 선택해야 한다. 그리고 그 후에 객체 내부의 데이터를 고려해야 한다.
책임 할당을 위한 GRASP 패턴
General Responsibility Assignment Software Pattern의 약자로 객체에게 책임을 할당할 때 지침으로 삼을 수 있는 원칙들의 집합을 패턴 형식으로 정리한 것이다.
설계를 시작하기 전에 도메인에 대한 개략적인(너무 구체적이지는 않은) 모습을 그려 보는 것이 유용하다.
Information Expert 패턴
책임을 수행할 정보를 알고 있는 객체에게 책임을 할당해야 한다.
정보를 알고 있는 객체만이 책임을 어떻게 수행할지 스스로 결정할 수 있기 때문이다.
이 때 정보는 반드시 객체에 저장하고 있는 데이터만을 의미하지는 않는다. 다른 객체로부터 정보를 받거나 계산해서 알 수도 있다.
LOW COUPLING 패턴, HIGH COHESION 패턴
여러 협력 패턴 중 낮은 결합도, 높은 응집력을 가진 설계를 선택해야 한다는 패턴이다.
책임을 할당하고 코드를 작성하는 매순간마다 이 패턴들의 관점에서 검토하면 단순하면서도 재사용 가능하고 유연한 설계를 얻을 수 있을 것이다.
CREATOR 패턴
객체를 생성할 책임을 어떤 객체에게 할당할 지에 대한 지침을 제공한다.
아래 조건을 최대한 많이 만족하는 B에게 객체 생성 책임을 할당한다.
B가 A 객체를 포함하거나 참조한다.
B가 A 객체를 기록한다.
B가 A 객체를 긴밀하게 사용한다.
B가 A 객체를 초기화하는데 필요한 데이터를 가지고 있다. 이 경우 B는 A에 대한 정보 전문가다.
POLYMORPHISM 패턴
객체의 타입에 따라 변하는 행동이 있다면, 타입을 분리하고 변화하는 행동을 각 타입의 책임으로 할당하는 방식
프로그램을 if ~ else 또는 switch ~ case 등의 조건 논리를 사용해서 설계한다면 새로운 변화가 일어난 경우 조건 논리를 수정해야 한다.
PROTECTED VARIATIONS 패턴
변화가 예상되는 불안정한 지점들을 식별하고 그 주위에 안정된 인터페이스를 형성하도록 책임을 할당하는 방식
구현을 통한 검증
메시지는 수신자 클래스가 아니라 송신자 클래스의 의도를 표현한다. 이를 통해 내부 구현에 대한 어떤 지식도 없이 전송할 메시지를 결정하게 되므로 캡슐화가 가능하다.
클래스가 하나 이상의 이유로 변경되어야 한다면 응집도가 낮은 것이다. 변경의 이유를 기준으로 클래스를 분리해야 한다.
코드를 통해 변경의 이유를 파악할 수 있는 방법
인스턴스를 생성할 때 모든 속성을 함께 초기화하는 경우 응집도가 높은 클래스이다. 따라서 함께 초기화되는 속성을 기준으로 코드를 분리해야 한다.
모든 메서드가 객체의 모든 속성을 사용한다면 클래스의 응집도가 높은 것이다. 반면 메서드들이 사용하는 속성에 따라 그룹이 나뉜다면 클래스의 응집도가 낮다고 볼 수 있으며, 이 때에는 그룹별로 코드를 분리해야 한다.
절차지향 코드 리팩토링
거대한 몬스터 메서드를 응집도 높은 여러 개의 메서드들로 쪼갠다.
각 메서드가 사용하는 데이터를 기준으로 각각의 클래스로 쪼갠다.
Polymorphism 패턴과 protected variations 패턴을 적용하여 캡슐화와 높은 응집도를 가지도록 한다.
Last updated