GoFの23パターンをまとめてみた

振る舞い

TemplateMethod
利用方法は固定、カスタマイズさえできればよい

呼び出し部分だけpublicにしてそこから呼び出す

継承してカスタマイズ部分を記述するだけ

再利用がしやすくなる

Iterator
データ構造の管理が複雑

管理クラスを作る

統一的なアクセス手段を提供できる

利用側がわかりやすくなる

Command
タイミングだけがわかっていて,具体的な内容が不定

コマンドを1つずつカプセル化

コマンドにが1つのオブジェクトになる

命令を集合として扱うことが可能に

State
状態遷移が複雑

状態を一つのクラスにして,クラス内で切り替える

複雑な条件分岐が減る

クラスは増えるが冗長性が消え,保守性は増す

Observer
状態の変化を通知させたりしたい

登録,解除を行うSubjectと,通知を受け取るObserverを作成

イベント駆動型プログラミングが可能になる

ObserverとSubjectの結合強度が減る

Strategy
アルゴリズムを状況に応じて選択したい

アルゴリズムをカプセル化する

複雑な条件分岐が減る

クラスは増えるが冗長性が消え,保守性は増す

Mediator
複数のオブジェクトが相互の作用している

まとめ役クラスを作る

各クラスはMediatorにのみ依存する

結合強度が減る

Visitor
新たな操作を構造を変更せずに既存のオブジェクトに追加したい

オブジェクト内のacceptメソッドで,Visitorのvisitメソッドに自分を渡して委譲する

アルゴリズムがオブジェクトの構造から分離される

アルゴリズムはVisitorによって多態的になる

Memento
カプセル化したまま状態を記録・復元できるようにしたい

オブジェクトが保持しているデータをそのオブジェクトだけがアクセスできるオブジェクトに保存

メモするときに作って,必要なときに開封するための専用クラスができる

一時的なセーブロードが可能になる

Interpreter
問題の解決手段として,規則の順序的な組み合わせを利用したい

規則や規則の集まりをオブジェクトとして表現する

規則がカプセル化される

追加や修正が容易になる

生成

Singleton
複数生成してしまうとまずいオブジェクトがある

オブジェクトの生成数を構造として制限する

生成側で今作られているオブジェクトを数える必要がない

生成側では何も考えずに作ってよい

使用例
通信のソケット

FactoryMethod
同じオブジェクトの生成の手順がいろいろなところにある

生成手順を1箇所にまとめる

生成する側は生成手順に依存しないコードを書ける

もし生成手順を変更する必要があったとしてもFactoryMethodのみの変更で済む

AbstructFactory
同じ手順で変化のあるものを生成したい

FactoryMethodを抽象化する

Factoryを切り替えるだけで生成されるオブジェクトも変わる

同じ手順で多様な生成が可能

使用例
GUIツールキット

Builder
アルゴリズムが複雑でスパゲッティ状態

生成部分と生成のアルゴリズム部分を分離

カプセル化できる

それぞれに集中できるので高機能にしやすい

Prototype
コピーがめんどい

自分をコピーして返す関数を作成

コピー元を引数にして生成

コピーが簡単

構造

Composite
似たような機能を持つクラスがたくさん

同一のインタフェースのノードにする

容器と中身を同一視できる

木構造を伴う再帰的なデータ構造を表すことができる

※一般化が過度になり,論理的に正しくない構造ができてしまうときがある

Adapter
インタフェースが違うが似た機能のクラスがある

インタフェースの違うクラスを継承し,さらに適応させたいインタフェース実装する

インタフェースを変えるだけのAdapterクラスができる

違うインタフェースのクラスもポリモーフィズムを使える

Facade
サブシステムが複雑

サブシステムの窓口クラスを作る

関連するクラス群が隠蔽される

サブシステムへの結合強度や依存性が減る

Proxy
外部のAPIやリソースに影響を受ける部分がある

代理のオブジェクトを介するようにする

高機能化を行うべき適切な場所が

元の本質的な動作を行う部分に変更を加えずに済む

Bridge
直列的に継承していくと,m*n*...個のクラスが必要

拡張する側で拡張元の参照を保持し,機能を参照先へ移譲する

拡張元が決定されなくなった

クライアント側で拡張の組み合わせを選ぶことで,m*n*...種類のオブジェクトが生成できる

Decorator
機能の拡張を柔軟にしたい

同じインタフェースで拡張する側で拡張元の参照を保持し,機能を参照先へ移譲する

拡張元が決定されなくなった

クライアント側で拡張の組み合わせを再帰的に選べるようになる

Flyweight
何度も同じリソースを生成するのは無駄

プールを作って,存在すれば既存のオブジェクト,存在しなければあたらしいオブジェクトを返す

オブジェクトを容易に使いまわせるようになる

オブジェクト生成のオーバーヘッドが減少