GRASPとは、General Responsibility Assignment Software PatternあるいはPrinciple(汎用的責任性割り当てパターン/原則)の頭字語であり、オブジェクト指向設計に向けた九つの原則セットまたはパターンセットである[1]。計算機科学者クレーグ・ラーマンの1997年著作「実践UMLパターン -Applying UML and Patterns-」で初めて紹介されている[2]。
「ソフトウェア開発において決定的な設計ツールになるのは、設計の原則の中で磨き上げられたメンタルであって、UMLやその他のテクノロジーではない」がラーマンの主張であり[3]、GRASPとはオブジェクト指向開発を助けるためのメンタルツール(mental tool)であると定義している[1]。
このパターンは、オブジェクトに責務を割り当てる際の一般的な原則である。情報エキスパートパターンは、情報のエキスパート、すなわち必要な情報を全て持っているクラスに責務を割り当てるべきとする。この原則は、ソフトウェアシステムにおいての責務と演算を集中させない(Big ball of mudとは対照的である)。責務と意思決定の分散が進むと情報の隠蔽化が促進され、他のクラスと情報エキスパートクラスの実装との結合の度合いが小さくなる。情報エキスパートパターンを適切に使いこなしたシステムは理解しやすく、維持・拡張が簡単で、また将来の開発で再利用できる可能性が高まる[4]。マーティン・ファウラーは、Web の記事 「GetterEradicator」でラーマンの情報エキスパートを参照している[5]。
このパターンは、オブジェクトが適切に責務を集中させており、管理・理解が可能な状態を保つための尺度である。高凝集性とは、ある要素の責務が強く関連しており、またその要素に集中していることを意味する。クラスやサブシステムにプログラムを分解するのは、システムの凝集性を高める活動の例だと言える。逆に凝集性が低いということは、関連のない責務を持ちすぎている場合である。凝集性が低い要素は理解が難しく、再利用・維持管理が困難で、変更も行いづらい[6]。
このパターンは、クラスの新しいインスタンスを作成することに責任を持つのは誰かという問題を解決する。オブジェクトの作成は、オブジェクト指向のシステムではあらゆるところで行われる活動であるから、生成者パターンは重要である。生成者パターンを有効に用いるシステムは、疎結合性が高くなり、理解のしやすさ、カプセル化が促進され、オブジェクトが今後再利用できる可能性が増加する。たとえば、二つのクラスA,Bがあったとき、B が A を包含する、A を合成・集約する、A を密接に使用する、A の初期化情報を持っているといった場合、クラス B がクラス A の作成に責任を持つべきであり、B は A の生成者として自然なオブジェクトと言える。Factoryパターンは、複雑なオブジェクト作成ロジックなど、特別な検討が必要な場合に、「生成者」の替わりになる方法である。この方法では、Factoryと呼ばれる「純粋な人工的」(後述)であるオブジェクトを作ってオブジェクトの作成を行わせることで目的を達する[7]。
このパターンは、システム全体やユースケースシナリオを表現するユーザインタフェースでないクラスにシステムイベントを扱う責務を割り当てる。ユースケースのコントローラはユースケースの全てのシステムイベントを扱い、複数のユースケースで使用できる(例えば、「ユーザーの作成」「ユーザーの削除」というユースケースで、それぞれUserControllerオブジェクトを持たずに一つのオブジェクトを共有してよい)。コントローラは、UI層以上にあって、システムに対する操作を受け取り調整する(制御する)最初のオブジェクトとして定義される。コントローラは、他のオブジェクトに必要な作業の実施を委譲する。他のオブジェクトの活動を制御し、連携させる。一般的なレイヤ構造を持ったオブジェクト指向のシステムでは、GRASP コントローラはアプリケーションやサービス層の一部と考えられる[8] (アプリケーション層/サービス層、ドメイン層を明確に区別している場合)。
このパターンは、二つの要素の中間にオブジェクトを設け両者の仲介を行う責務を割り当てることで、二つの要素間の疎結合性(および再利用の可能性)を促進する。Model View Controllerにおいてコントローラがデータ(モデル)と表現(ビュー)の仲介を行うのはその一例と言える。
このパターンは、型に基づいて振る舞いの変動部分を定義する責務を、変動が起きる型に割り当てる。これは、ポリモルフィックな操作を持たせることで実現できる。
このパターンは、周辺の要素(オブジェクト、システム、サブシステム)の変動から注目する要素を保護するために、不安定な部分をインタフェースを用いて収束させ、ポリモーフィズムを用いてインターフェイスを実装させる。
このパターンは、問題領域に登場する概念を表すクラスではなく、疎結合や、高凝集性、それらから得られる再利用可能性を実現するために作られるクラスである(情報エキスパートで実現できない場合)。この種類のクラスはドメイン駆動設計ではサービスと呼ばれる。