Assigning Responsibilities (클래스 설계 시 어떤 클래스에 책임을 부여할 것인가를 결정하는 원칙) (註) 이 내용은 주로 Applying UML and Patterns - An Introduction to Object-Oriented Analysis and Design by Craig Larman 에서 발췌한 것입니다. (註) GRASP : General Responsibility Assignment Software Patterns 차례 1. responsibility란 무엇인가? 2. GRASP * Expert * Creator * High Cohesion * Low Coupling * Controller * Polymorphism * Pure Fabrication * Indirection * Don't talk to Strangers 3. several OO maxims * encapsulate the concept that varies * program to an interface, not an implementation * favor object composition over class inheritance == responsibility란 무엇인가? == a contract or obligation of a type or class (Booch and Rumbaugh) 책임은 행동의 관점에서 객체의 의무와 관련이 있다. 책임은 보통 1. knowing, 2. doing 두 가지 유형으로 나뉜다. doing * doing something itself * initiating action in other objects * controlling and coordinating activities in other objects knowing * knowing about private encapsulated data * knowing about related objects * knowing about things it can derive or calculate 책임은 메소드와 같지는 않지만 책임을 충족시키기 위해 메소드를 구현한다. 즉, 책임을 구현하기 위해 혼자 동작하는, 혹은 다른 메소드나 객체와 협업하는 메소드들을 사용한다. == GRASP == === Expert === 1. 사용법 * 정보 전문가(어떤 일을 수행하는 데 필요한 정보를 가진 클래스)에게 책임을 맡겨라. 1. 적용 영역 * 객체에게 책임을 부여하는 가장 기본적인 원칙. 1. 유사어 * Place responsibilities with data * That which knows, does. * Animation * Do it Myself * Put Services with the Attributes The Work On 1. 기타 === Creator === 1. 사용법 * 다음 조건들 중 하나라도 만족하면, A 클래스의 인스턴스를 생성할 책임을 B 클래스에게 맡겨라. * B가 A 객체들의 aggregates일 때 * B가 A 객체를 포함할 때 * B가 A 객체들의 인스턴스를 기록할 때 * B가 A 객체들을 밀접하게 사용할 때 * B가 A를 생성할 때 넘겨줄 초기 데이터를 가지고 있을 때 (이 경우 B가 A를 만드는 일에 대해서 Expert이다.) 1. 적용 영역 * 누가 어떤 클래스의 인스턴스를 생성할 책임을 질 것인가? 1. 유사어 1. 기타 * Low Coupling 참조. === Low Coupling === 1. 사용법 * Coupling(결합도)이 low가 되도록 책임을 맡겨라. 1. 적용 영역 * 어떻게 dependency를 줄이고 재사용을 용이하게 할 것인가? 1. 유사어 1. 기타 * Coupling이란 어떤 클래스가 다른 클래스들에 얼마나 강하게 연결되었는지, 많이 알고 있는지, 혹은 의존하고 있는지에 대한 척도이다.low(혹은 weak) coupling으로 된 클래스는 지나치게 많은 다른 클래스들에게 의존하지 않는다. 의존 정도가 지나치면 다음 문제가 생긴다. * 관련 클래스의 변경이 이 클래스 수정을 강요한다. * 이 클래스 하나만 놓고 보면 이해하기가 어렵다. * 이 클래스를 사용하기 위해서는 이 클래스가 의존하는 클래스들이 필요하기 때문에 재사용이 어렵다. === High Cohesion === 1. 사용법 * Cohesion(응집도)이 high가 되도록 책임을 맡겨라. 1. 적용 영역 * 어떻게 복잡한 것을 용이하게 유지할 것인가? 1. 유사어 1. 기타 * 객체지향 설계 용어로서 Cohesion(기능적 cohesion)이란 어떤 클래스의 책임들이 얼마나 강하게 연결되어 있는지 그리고 집중되어 있는지에 대한 척도이다. high cohesion을 가진 클래스는 아주 관련이 큰 책임들로 구성되어 있으며 지나치게 많은 일을 하지 않는 클래스이다. cohesion이 높지 않은 클래스들은 많은 관련 없는 일들을 하거나 지나치게 많은 일을 하는데 다음 문제들을 안게 된다. * 이해하기가 어렵다. * 재사용하기가 어렵다. * 유지하기가 어렵다. * 세심한 주의가 필요하며 변화에 의해 계속 영향을 받는다. === Controller === 1. 사용법 * 시스템 이벤트 메시지 처리는 다음 중 하나를 나타내는 클래스에게 책임을 맡겨라. * 전체 시스템을 나타내는 클래스(facade controller) * 전체 업무나 조직구성을 나타내는 클래스(facade controller) * 실제 세계에서 해당 작업에 포함되어 있는 active인 것(예를 들면 어떤 사람의 역할)을 나타내는 클래스(role controller) * 어떤 use case의 모든 시스템 이벤트를 처리하는 핸들러(보통 이름이 Handler인 클래스)를 나타내는 클래스(use-case controller) 1. 적용 영역 * 누구에게 시스템 이벤트를 처리하는 책임을 맡길 것인가? 1. 유사어 1. 기타 * 잘못 설계하면 controller 클래스는 low cohesion이 되기 쉽다. 집중되지 않은 너무 많은 책임 영역을 처리할 때 이런 문제(bloated controller라고 한다)가 발생한다. * 일반적으로 role controller는 자주 사용해서는 안되며, 사람의 역할을 하는 객체에게 모든 일을 맡기는 것은 피해야 한다. === Polymorphism === 1. 사용법 * 관련된 대체 기능이나 행위들이 유형(클래스)에 따라 변할 때에는 이 행위들에 대한 책임을 이 행위가 (polymorphic operation에 의해) 변하는 그 유형에 대해 맡겨라. 1. 적용 영역 * 어떻게 유형에 기반한 대체 행위들을 처리할 것인가? 어떻게 pluggable한 소프트웨어 컴포넌트를 만들 것인가? 1. 유사어 * Do it Myself * Choosing Message * Don't Ask 'What Kind?' 1. 기타 === Pure Fabrication === 1. 사용법 * 매우 응집된 책임들의 집합은 high cohesion, low coupling, reuse를 위해 problem domain의 어떤 것도 나타내지 않는, 인위적으로 만든 클래스에 맡겨라. 1. 적용 영역 * 절실하게 High Cohesion 과 Low Coupling을 위반하고 싶지 않을 때. 1. 유사어 1. 기타 * 보통 Pure Fabrication은 관련된 기능들에 기반하여 분리되므로, 좋은 객체 지향 설계는 기능 중심이 아니라 객체 중심이어야 한다는 취지가 훼손되기 쉽다. === Indirection === 1. 사용법 * 서로 다른 컴포넌트나 서비스들이 직접 couple되지 않도록 중재하기 위해 중간 객체에게 책임을 맡겨라. 1. 적용 영역 * 직접적인 coupling을 피하고자 할 때. * 어떻게 하면 Low Coupling을 지원하고 reuse 가능성을 높이도록 객체들을 de-couple할 것인가? 1. 유사어 1. 기타 === Don't Talk to Strangers === 1. 사용법 * 클라이언트가 어떤 간접 객체와 협업할 때 클라이언트가 이 간접 객체에 대해 알 필요가 없도록 클라이언트의 직접적인 객체에게 책임을 맡겨라. 이 패턴은 메소드 안에서 메시지를 보낼 수 있는 대상 객체들에 제약을 둔다. 즉, 메소드 안에서 메시지는 다음 객체들에게만 보내야 한다. * this 객체 (즉, 자신) * 메소드의 인자 * 자신의 필드 속성 * 자신의 필드 속성인 컬렉션의 한 원소 * 메소드 안에서 만든 객체 1. 적용 영역 * 간접 객체들의 구조에 대해 아는 것을 피하려면 어떻게 해야 하는가? 1. 유사어 * Law of Demeter([그神〕 데메테르. 대지의 생산을 관장하는 여신; 로마 신화의 Ceres에 해당함.) 1. 기타 == 몇 가지 객체 지향 설계의 격언들 == * encapsulate the concept that varies * program to an interface, not an implementation * favor object composition over class inheritance