GRASP

**GRASP**(General Responsibility Assignment Software Patterns 혹은 Principles)는 크레이그 라만이 1997년 저서 《UML과 패턴의 적용》(Applying UML and Patterns)에서 처음 발표한 "객체 설계 및 책임 할당의 9가지 기본 원칙"이다.

GRASP에서 사용되는 다양한 패턴과 원칙은 컨트롤러(controller), 생성자(creator), 간접 참조(indirection), 정보 전문가(information expert), 낮은 결합도(low coupling), 높은 응집도(high cohesion), 다형성(polymorphism), 변경 보호(protected variations), 순수 가공(pure fabrication)이 있다. 이 모든 패턴은 많은 소프트웨어 개발 프로젝트에서 공통적으로 발생하는 몇 가지 소프트웨어 문제를 해결한다. 이러한 기법들은 새로운 작업 방식을 만들기 위해 발명된 것이 아니라, 객체 지향 설계에서 오래되고 검증된 프로그래밍 원칙을 더 잘 문서화하고 표준화하기 위해 만들어졌다.

라만은 "소프트웨어 개발을 위한 핵심 설계 도구는 설계 원칙에 대해 잘 교육된 정신이다. UML이나 다른 기술이 아니다"라고 명시했다. 따라서 GRASP 원칙은 실제로는 객체 지향 소프트웨어 설계를 돕는 정신적인 도구 세트이자 학습 보조 도구이다.

## 패턴
객체 지향 설계에서 패턴은 새로운 맥락에 적용할 수 있는 문제와 해결책에 대한 명명된 설명이다. 이상적으로 패턴은 다양한 상황에서 해결책을 적용하는 방법과 힘의 관계 및 트레이드오프를 고려하도록 조언한다. 특정 범주의 문제가 주어졌을 때, 많은 패턴이 객체에 책임을 할당하는 지침을 제공한다.

### 정보 전문가 (Information expert)

문제: 객체에 책임을 할당하는 기본 원칙은 무엇인가?
해결책: 책임을 수행하는 데 필요한 정보를 가진 클래스에 책임을 할당하라.

**정보 전문가**(또는 **전문가** 또는 **전문가 원칙**)는 메서드, 계산된 필드 등과 같은 책임을 어디에 위임할지 결정하는 데 사용되는 원칙이다.

정보 전문가 원칙을 사용하는 일반적인 책임 할당 접근 방식은 주어진 책임을 살펴보고, 이를 수행하는 데 필요한 정보를 결정한 다음, 해당 정보가 어디에 저장되어 있는지 확인하는 것이다.

이는 책임을 완수하는 데 필요한 정보가 가장 많은 클래스에 책임을 배치하도록 유도한다.

**관련 패턴 및 원칙**: 낮은 결합도, 높은 응집도

### 생성자 (Creator)

객체의 생성은 객체 지향 시스템에서 가장 흔한 활동 중 하나이다. 어떤 클래스가 객체 생성의 책임을 갖는지는 특정 클래스 객체들 간의 관계의 기본 속성이다.

문제: 객체 `A`를 누가 생성해야 하는가?
해결책: 일반적으로 다음 중 하나 이상에 해당할 경우 클래스 `B`에 객체 `A`를 생성할 책임을 할당한다.
* `B`의 인스턴스가 `A`의 인스턴스를 포함하거나 복합적으로 집합한다.
* `B`의 인스턴스가 `A`의 인스턴스를 기록한다.
* `B`의 인스턴스가 `A`의 인스턴스를 밀접하게 사용한다.
* `B`의 인스턴스가 `A`의 인스턴스를 위한 초기화 정보를 가지고 있으며, 생성 시 이를 전달한다.

**관련 패턴 및 원칙**: 낮은 결합도, 팩토리 패턴

### 컨트롤러 (Controller)

**컨트롤러** 패턴은 시스템 이벤트를 처리하는 책임을 전체 시스템 또는 유스 케이스 시나리오를 나타내는 비-UI 클래스에 할당한다. 컨트롤러 객체는 시스템 이벤트를 수신하거나 처리하는 책임을 지는 비사용자 인터페이스 객체이다.

문제: 입력 시스템 이벤트를 처리하는 책임은 누구에게 있는가?
해결책: 유스 케이스 컨트롤러를 사용하여 유스 케이스의 모든 시스템 이벤트를 처리해야 하며, 하나 이상의 유스 케이스에 사용될 수 있다. 예를 들어, '사용자 생성' 및 '사용자 삭제' 유스 케이스에 대해 두 개의 개별 유스 케이스 컨트롤러 대신 UserController라는 단일 클래스를 가질 수 있다. 대안으로 파사드(facade) 컨트롤러를 사용할 수 있는데, 이는 이벤트를 처리할 책임이 있는 객체가 전체 시스템이나 루트 객체를 나타낼 때 적용된다.

컨트롤러는 UI 계층 너머에서 시스템 작업을 수신하고 조정("제어")하는 첫 번째 객체로 정의된다. 컨트롤러는 수행해야 할 작업을 다른 객체에 위임해야 하며, 활동을 조정하거나 제어한다. 컨트롤러 자체가 많은 일을 해서는 안 된다. GRASP 컨트롤러는 정보 시스템 논리 아키텍처의 일반적인 계층을 가진 객체 지향 시스템에서 (애플리케이션/서비스 계층과 도메인 계층을 명확히 구분했다고 가정할 때) 애플리케이션/서비스 계층의 일부로 간주될 수 있다.

**관련 패턴 및 원칙**: 커맨드, 파사드, 계층, 순수 가공

### 간접 참조 (Indirection)
간접 참조 패턴은 두 요소 사이에 중재 책임을 맡는 중간 객체를 할당함으로써 낮은 결합도를 지원하고 재사용 가능성을 높인다. 모델-뷰-컨트롤러 패턴에서 데이터(모델)와 그 표현(뷰) 사이의 중재를 위해 컨트롤러 구성 요소를 도입하는 것이 그 예시이다. 이를 통해 구성 요소 간의 결합도를 낮게 유지할 수 있다.

문제: 두 가지(또는 그 이상) 항목 간의 직접적인 결합을 피하기 위해 책임을 어디에 할당해야 하는가? 낮은 결합도를 지원하고 재사용 가능성을 높게 유지하기 위해 객체를 어떻게 분리하는가?

해결책: 다른 구성 요소나 서비스 사이에서 중재하는 중간 객체에 책임을 할당하여 직접 결합되지 않도록 한다.
중재자는 다른 구성 요소들 사이에 **간접 참조**를 생성한다.

### 낮은 결합도 (Low coupling)

결합도는 한 요소가 다른 요소와 얼마나 강하게 연결되어 있는지, 다른 요소에 대한 지식을 얼마나 가지고 있는지, 또는 다른 요소에 얼마나 의존하는지를 나타내는 척도이다. **낮은 결합도**는 다음과 같은 이점을 위해 책임을 할당하는 방법을 규정하는 평가 패턴이다.
* 클래스 간의 의존성 감소
* 한 클래스의 변경이 다른 클래스에 미치는 영향 감소
* 재사용 가능성 증대

### 높은 응집도 (High cohesion)

**높은 응집도**는 객체가 적절하게 집중되고, 관리 가능하며, 이해하기 쉬운 상태를 유지하도록 하는 평가 패턴이다. 높은 응집도는 일반적으로 낮은 결합도를 지원하기 위해 사용된다. 높은 응집도는 주어진 요소 세트의 책임이 밀접하게 연관되어 있고 상당히 구체적인 주제에 집중되어 있음을 의미한다. 프로그램을 클래스와 하위 시스템으로 나누는 작업을 올바르게 수행하면 명명된 클래스와 하위 시스템의 응집력을 높이는 활동의 예가 된다. 반대로 낮은 응집도는 하위 시스템 등과 같은 요소 세트가 서로 관련 없는 책임을 너무 많이 가지고 있는 상황이다. 구성 요소 간의 응집도가 낮은 하위 시스템은 전체로서 이해, 재사용, 유지 관리 및 변경하기 어렵다는 단점이 있다.

### 다형성 (Polymorphism)

**다형성** 원칙에 따르면, 타입에 따라 달라지는 행동의 변화를 정의하는 책임은 이러한 변화가 발생하는 타입에 할당된다. 이는 다형성 연산을 사용하여 달성된다. 해당 타입을 사용하는 사용자는 타입에 따른 명시적인 조건문(branching) 대신 다형성 연산을 사용해야 한다.

문제: 타입에 따른 대안을 어떻게 처리하는가? 교체 가능한(pluggable) 소프트웨어 구성 요소를 어떻게 만드는가?
해결책: 관련 대안이나 행동이 타입(클래스)에 따라 달라질 때, 다형성 연산을 사용하여 행동이 변하는 타입에 해당 행동에 대한 책임을 할당하라. (다형성은 여러 관련 의미를 갖는다. 이 문맥에서는 "서로 다른 객체의 서비스에 동일한 이름을 부여하는 것"을 의미한다.)

### 변경 보호 (Protected variations)

**변경 보호** 패턴은 불안정성의 중심을 인터페이스로 래핑하고 다형성을 사용하여 이 인터페이스의 다양한 구현을 생성함으로써, 다른 요소(객체, 시스템, 하위 시스템)의 변화로부터 요소를 보호한다.

문제: 요소의 변화나 불안정성이 다른 요소에 바람직하지 않은 영향을 미치지 않도록 객체, 하위 시스템 및 시스템을 설계하는 방법은 무엇인가?
해결책: 예상되는 변화나 불안정 지점을 식별하고, 그 주변에 안정적인 인터페이스를 형성하도록 책임을 할당하라.

### 순수 가공 (Pure fabrication)

**순수 가공**은 문제 도메인의 개념을 나타내지는 않지만, 낮은 결합도, 높은 응집도 및 거기서 파생되는 재사용 가능성을 달성하기 위해 특별히 만들어진 클래스이다(정보 전문가 패턴이 제시하는 해결책으로 이것이 불가능할 때 사용). 이러한 종류의 클래스는 도메인 주도 설계에서 "서비스"라고 불린다.

**관련 패턴 및 원칙**
• 낮은 결합도.
• 높은 응집도.

## 같이 보기
* 빈약한 도메인 모델
* 디자인 패턴 (컴퓨터 과학)
* 디자인 패턴 (책)
* SOLID (객체 지향 설계)

## 각주




분류:소프트웨어 설계
분류:프로그래밍 원칙