デザインパターンの種類


 

デザインパターンの種類

デザインパターンの種類

デザインパターンは 23種類あり、次の3つに分類されています。

また、ぞれぞれに内容を表す名前が付けられています。その名前からは、何かしら特定のパターンが想像できます。

オブジェクトの「生成」に関するパターン

【有用度】
Abstract Factory  抽象的な工場★☆☆

互いに関連したり依存したりするオブジェクト群をその具象クラスを明確にせずに生成するためのインターフェースを提供する。

Builder  構築者★★☆

複合オブジェクトについて、その作成過程を表現形式に依存しないものにすることにより、同じ作成過程で異なる表現形式のオブジェクトを生成できるようにする。

Factory Method  工場メソッド★★★

オブジェクトを作成するときのインターフェースだけを規定して、実際にどのクラスをインスタンス化するかはサブクラスが決定するようにする。

Prototype  原型★★☆

原型となるインスタンスを使って生成すべきオブジェクトの種類を明確にし、この原型をコピーすることで新しいオブジェクトを生成する。

Singleton  一人っ子★★★

クラスが1つだけインスタンスを持つことを保証し、そのインスタンスにアクセスするためのグローバルな方法を提供する。

プログラムの「構造」に関するパターン

【有用度】
Adapter  接続装置★★☆

クラスのインターフェースを、クライアントが求める他のインターフェースに変換する。互換性がないインターフェースのために組み合わせることができないクラス同士を組み合わせることができるようにする。

Bridge  ★★☆

抽象概念とその実装を分離して、それらを独立に変更できるようにする。

Composite  合成物★☆☆

階層構造を表現するためにオブジェクトを木構造に組み立てる。個々のオブジェクトとそのオブジェクトを合成したものを一様に扱うことができる。

Decorator  装飾者★★☆

オブジェクトに付加的な機能を動的に追加する。Decoratorパターンは継承よりも柔軟な拡張方法を提供する。

Façade  見かけ★☆☆

サブシステムの複数のインターフェースに1つの統一されたインタフェースを与える。サブシステムの利用を用意にするための高レベルのインターフェースを定義する。

Flyweight  軽量級★★☆

多数の小さいオブジェクトを効率よくサポートするために共有を利用する。

Proxy  代理人★☆☆

あるオブジェクトへのアクセスを制御するために、そのオブジェクトの代理または入れ物を提供する。

プログラムの「振る舞い」に関するパターン

【有用度】
Chain of Responsibility  責任の連鎖★☆☆

1つ以上のオブジェクトに要求を処理する機会を与えることにより、要求を送信するオブジェクトと受信するオブジェクトの結合を避ける。要求を受信する複数のオブジェクトをチェーン状につなぎ、あるオブジェクトがその要求を処理するまでそのチェーンに沿って要求を渡していく

Command  命令★★☆

要求をオブジェクトとしてカプセル化することによって、様々な要求または要求からなるキューやログによりクライアントをパラメータ化する。そして、取り消し可能な操作をサポートする。

Interpreter  通訳★☆☆

言語に対して、文法表現と、それを利用して文を解釈するインタプリタを一緒に定義する。

Iterator  繰り返し★★★

集約オブジェクトの内部表現を公開せずに、その集約オブジェクトの要素を順にアクセスする方法を提供する。

Mediator  調停者★★☆

多数のオブジェクトの間の調整を行いながら処理をすすめる方法を提供する。オブジェクト同士がお互いを明示的に参照し合うことがないようにして、結合度を低めることを促進する。それにより、オブジェクトの相互作用を独立に変えることができるようにする。

Memento  形見★☆☆

カプセル化を破壊せずに、オブジェクトの内部状態を捉えて外面化しておき、オブジェクトを後でこの状態に戻すことができるようにする。

Observer  観察者★☆☆

あるオブジェクトの状態が変わった時に、それに依存するすべてのオブジェクトに自動的にそのことが知らされ更新されるように、オブジェクト間に一対多の依存関係を定義する。

State  状態★★★

オブジェクトの内部状態が変化したときにオブジェクトの処理内容を変えられるようにする。

Strategy  戦略★★☆

アルゴリズムの集合を定義し、それぞれのアルゴリズムをカプセル化してそれらを交換可能にする。アルゴリズムを、それを利用するクライアントから独立に変更できるようにする。

Template Method  ひな型メソッド★★★

ある処理においてアルゴリズムのスケルトンを定義し、その中のいくつかのステップはサブクラスでの定義に任せる。アルゴリズムの構造を変化させることなしにアルゴリズム中のあるステップをサブクラスで再定義させる。

Visitor  訪問者★★☆

オブジェクトの構造上の要素で実行される処理を表現する。処理を加えるクラスを変更することなしに新しい処理を定義できるようになる。

設計への利用

デザインパターンは、そのまま現在直面している問題の解決につながるようなものではありません。デザインパターンを学習して、なぜこれらが良い設計とされているのかを理解することが大切なのです。これらの設計のキモをつかむことで、明日からの設計が少しずつ変わってくるはずです。

さて、ではデザインパターンはどのように設計者を助けてくれるのでしょう。設計に困ったといっても困り方もいろいろあります。ここではデザインパターンを思い出すべき場面をいくつか紹介しようと思います。

クラスの抽出

オブジェクト指向では、基本的に現実世界に即した形で設計するとよく言われますが、実は、現実世界には存在しない抽象的なものをクラスとして抽出することがあります。しかし、抽象的な概念をクラスにするという設計に至るのは難しいのです。

デザインパターンには、このような抽象的な概念をうまく取り入れたものがいくつかあります。例えばStrategy パターンというパターンでは「戦略」をクラスとして抽出していますし、State パターンでは「状態」というさらに抽象的なものをクラスとして抽出しています。

デザインパターンを学習することで、このような抽象的なものをクラスとして抽出する感覚が身についてきます。現実世界だけを見ていると、なかなか設計がうまくいかないことがあります。こんなときは、デザインパターンを思い出して、抽象的な概念をクラスとして抽出することを考えてみましょう。

実装とインタフェースの切り分け

デザインパターンでは、インタフェースに対してプログラミングすることが積極的に取り入れられています。デザインパターンを学習していくと、インタフェースを使うことのすばらしさに気付かされます。具象クラスを変数宣言している場面では「インタフェースにしておいたほうが良いのではないか」と常に自分に問いかけるようにしましょう。

再利用性を高める

デザインパターンでは、継承やオブジェクトコンポジション(別のオブジェクトが持つ機能を組み合わせて利用すること)がとてもうまく利用されており、とても参考になります。再利用性を高めたいときには、ぜひともこれを思い出すようにしてください。 デザインパターンでは、オブジェクトコンポジションを多用することを理想的としています。オブジェクトを組み合わせることで、必要とする機能の全てが用意できるようになることが、再利用性が最も高まった状態と言えるからです。

変更に強くする

仕様の追加や変更に柔軟に対応できるような設計が、優れた設計であることは言うまでもありません。仕様の追加や変更が発生するたびに、設計から見直すことは、大きなコスト増につながります。設計の変更には、クラスの変更、実装の変更、再テストなどを伴うからです。仕様の追加や変更に柔軟に対応するためには、あらかじめ起こりうる追加や変更を想定しておく必要があります。デザインパターンは、想定される仕様の追加や変更に柔軟に対応できる方法を教えてくれます。