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
何度も同じリソースを生成するのは無駄
↓
プールを作って,存在すれば既存のオブジェクト,存在しなければあたらしいオブジェクトを返す
↓
オブジェクトを容易に使いまわせるようになる
↓
オブジェクト生成のオーバーヘッドが減少
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
何度も同じリソースを生成するのは無駄
↓
プールを作って,存在すれば既存のオブジェクト,存在しなければあたらしいオブジェクトを返す
↓
オブジェクトを容易に使いまわせるようになる
↓
オブジェクト生成のオーバーヘッドが減少