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