図解/デザインパターン一覧 (GoF)
本記事では、GoF によって定義された23種類のデザインパターンをざっくりとご紹介します。
これからデザインパターンを学習してみたい、というかたの手助けができれば幸いです。
各パターンの詳細については別途記事にまとめています。
そちらも合わせてご確認ください。
デザインパターンとは
デザインパターンとは、偉大な先人達により発見・編み出された設計のノウハウ集です。
その中でも GoF (Gang of Four) と呼ばれる4人によって定義されたパターンについて、本記事ではご紹介します。
デザインパターンを理解すれば、きっと設計の補助として役立つことでしょう。
デザインパターン一覧
生成に関するパターン
パターン名 | おすすめ度 | 説明 |
---|---|---|
Abstract Factory | ☆☆ | 関連する複数のオブジェクトの生成処理を、動的にまとめて切り替えます。 |
Builder | ☆☆ | 複雑なオブジェクト生成処理をシンプルにします。また、同じ手続きで異なる型のオブジェクトを生成できます。 |
Factory Method | ☆☆ | ベースとなるクラスで共通の処理を実装して、その処理で使うオブジェクトの生成処理はサブクラスに任せます。 |
Prototype | ☆☆ | 自身の属性を引き継いだ新しいオブジェクトを生成します。 |
Singleton | ☆ | そのクラスのインスタンスが1つしか生成されないことを保証します。 |
構造に関するパターン
パターン名 | おすすめ度 | 説明 |
---|---|---|
Adapter | ☆☆ | 既存のクラスの修正なしに、インタフェースを変更して再利用できます。 |
Bridge | ☆☆ | 複雑になる継承関係を、委譲を使ってシンプルにします。 |
Composite | ☆☆ | 木構造を持つ再帰的なデータ構造を実現します。 |
Decorator | ☆☆ | 機能を入れ子構造で持つことにより、複数の機能を動的に追加できます。 |
Facade | ☆☆ | 複雑な操作が必要となるサブシステムに対して、シンプルなインタフェースを提供します。 |
Flyweight | ☆☆ | 同じ内容のオブジェクトを再利用して、リソースを節約します。 |
Proxy | ☆☆ | 操作対象のオブジェクトを直接操作はせずに、代理人をとおして操作します。 |
振る舞いに関するパターン
パターン名 | おすすめ度 | 説明 |
---|---|---|
Chain of Responsibility | ☆☆ | 必要に応じて、一連のオブジェクトにリクエストを転送します。 |
Command | ☆☆ | 処理の依頼(リクエスト) と 処理の実行を分離します。 |
Interpreter | ☆☆ | 独自のドメイン固有言語(DSL) を実装します。 |
Iterator | ☆☆ | コンテナの要素を、共通のインタフェースで順々にアクセスします。 |
Mediator | ☆☆ | 相互に依存する複数のクラスがある場合に、その依存関係をシンプルにします。 |
Memento | ☆☆ | オブジェクトの 非公開(private) な内部状態を保存・復元します。 |
Observer | ☆☆☆ | イベントを不特定多数に通知できます。依存関係の向きを逆転させるテクニックとしても使えます。 |
State | ☆☆ | オブジェクトの状態を「振る舞いを持たせたクラスオブジェクト」で表します。 |
Strategy | ☆☆☆ | プログラムの実行時に、処理を動的に切り替えます。 |
Template Method | ☆☆ | ベースとなるクラスで処理の大まかな流れを実装して、具体的な実装はサブクラスに任せます。 |
Visitor | ☆☆ | 複数の異なるクラスに対して、それらのクラスの変更なしで一連の処理を拡張します。 |
学習の前に
最初に学ぶべきパターン
GoF によるデザインパターンは全部で23種類あります。
うわー、多いな … と感じるかたもいることでしょう。
しかし、実は似たようなパターンも多いのです。
代表的なパターンが理解できれば、他も応用でなんとかなります。
というわけで、最初に学ぶべきおすすめのパターンは
の2つです。
汎用性が高く、応用もしやすいパターンです。
この2つはじっくりと学び、よく理解することをおすすめします。
デザインパターンを過信しない
デザインパターンは、もちろんメリットがあるからこそ、こうしてパターンとしてまとめられています。
しかし、万能ではありません。
- デザインパターンが 最善ではない ときもある
- デザインパターンには デメリット もある
このことは、頭の片隅に置いておいたほうがよいでしょう。
例えば…
- なんでもかんでもデザインパターンを適用
↓ - 無駄にクラス構成が複雑になってしまった…
なんてことも。
個人的にですが、Singleton パターン はあまりおすすめしません。
そのあたりの話は下記の記事でまとめているので、興味のあるかたはご参照ください。
大事なことは、パターンの本質をよく理解することです。
パターンがそのまま適用できればよいのですが、そうでないときもあります。
ある程度、応用が必要なことも多いです。本質を理解していないと、応用も難しくなるでしょう。
メリットを実感しにくい
先ほどは、パターンの本質を理解することが大事だ、とお伝えしました。
しかし、それが難しいこともあります。
というのも、デザインパターンのメリットの多くは
- 機能の拡張がしやすくなる
という点だからです。
いわゆる 開放閉鎖の原則
- ソフトウェア要素(クラス、モジュール、関数など)は、拡張に対しては開いており、修正に対しては閉じているべきである。
ですね。
リーダー「急遽 仕様の追加 が決まりました。リリース間近だから、特に デグレ には注意してください」
Aさん「は、はい…」
なんて場面で真価を発揮します。
逆にいうと、このような仕様の追加(機能の拡張) がないと、デザインパターンのメリットが実感しにくい … かもれません。
デザインパターンを使わずに、べたっと書いたほうがコードが読みやすい、ということもあるでしょう。
悩ましいですね。
すぐにメリットの実感がわかなくても、長い目で見るのがよいのかな … と思います。
生成に関するパターン
Abstract Factory
Abstract Factory パターンとは、
- 関連する複数のオブジェクトがあり、
- そのオブジェクトの生成処理を、動的に まとめて 切り替える
という設計です。
また、
- 生成するオブジェクトの組み合わせを間違えないようにする
という効果もあります。
Abstract Factory は、日本語的に発音すると「アブストラクト・ファクトリ」となります。
意味は「抽象的な工場」ですね。
関連記事 :
Builder
Builder パターンとは、
- 複雑なオブジェクト生成処理をシンプルにする
- 同じ手続きで異なる型のオブジェクトを生成する
という2つの目的をもった設計です。
Builder は、日本語的に発音すると「ビルダー」となります。
意味は「建築者」ですね。
関連記事 :
Factory Method
Factory Method パターンとは、
- 処理はベースクラスで共通化
- 部品となるオブジェクトの生成処理はサブクラスで実装
という設計です。
Factory Method は、日本語的に発音すると「ファクトリ・メソッド」となります。
意味は「工場メソッド」ですね。
関連記事 :
Prototype
Prototype パターンとは、
- 自身の属性を引き継いだ新しいオブジェクトを生成する
という設計です。
Prototype は、日本語的に発音すると「プロトタイプ」となります。
意味は「原型」または「試作品」ですね。
関連記事 :
Singleton
Singleton パターンとは、
- あるクラスがあり
- そのクラスのインスタンスが最大で1つしか生成されない
ということを保証するための設計です。
Singleton は、日本語的に発音すると「シングルトン」となります。
意味は「単集合」ですね。
関連記事 :
構造に関するパターン
Adapter
Adapter パターンとは、
- 既存のクラスの 修正なし に、インタフェースを変更して再利用する
という設計です。
Adapter は、日本語的に発音すると「アダプター」となります。
意味は「適合させるもの」ですね。
日本語でもそのまま「アダプター」で使われているので馴染みやすいかと思います。
関連記事 :
Bridge
Bridge パターンとは、
- 複雑になる継承関係を、委譲 を使ってシンプルにする
という設計です。
Bridge は、日本語的に発音すると「ブリッジ」となります。
意味は「橋」ですね。
関連記事 :
Composite
Composite パターンとは、
- 木構造を持つ再帰的なデータ構造
を実現するための設計です。
Composite は、日本語的に発音すると「コンポジット」となります。
意味は「合成物」や「混合物」です。ただ、日本語に訳しても、あまりピンとはこないかも…です。
関連記事 :
Decorator
Decorator パターンとは、
- 機能を 入れ子 構造で持つことにより
- 複数の機能 を動的に追加する
という設計です。
Decorator は、日本語的に発音すると「デコレータ」となります。
意味は「装飾者」ですね。「デコレーション」ケーキなど、日本語でもそのまま使われていたりします。
関連記事 :
Facade
Facade パターンとは、
- 複雑な操作や連携が必要となるクラス群 (サブシステム、モジュールなど) があり
- 上記に対して、使いやすいシンプルなインタフェースを提供する
という目的のための設計です。
もっと簡単にいうと、
- 複雑な処理をまとめる
ということです。
サブルーチン の考え方をもう少し広げた感じでしょうか。
Facade は、日本語的に発音すると「ファサード」となります。
意味は「建物の正面」ですね。
関連記事 :
Flyweight
Flyweight パターンとは、内容の同じオブジェクトが必要となる場合に、
- 複数のオブジェクトは作らない
- 1つのオブジェクトを再利用(共有) してリソースを節約する
という設計です。
例えば、
- 大きなオブジェクトを使う
- 小さなオブジェクトでも大量に生成する
といったケースで有用でしょう。
Flyweight パターンは、特に 不変オブジェクト と相性のよいパターンです。
Flyweight は、日本語的に発音すると「フライウェイト」となります。
意味は「フライ級」で、ボクシングなどの格闘技で使われる階級の1つです。階級のなかでも体重が軽めの階級ですね。
関連記事 :
Proxy
Proxy パターンとは、
- 操作対象のオブジェクトがあるけど 直接操作はしない
- 代理人をとおして操作する
という設計です。
Proxy は、日本語的に発音すると「プロキシ」や「プロキシー」となります。
意味は「代理人」ですね。
関連記事 :
振る舞いに関するパターン
Chain of Responsibility
Chain of Responsibility パターンとは、
- ある一連のオブジェクト A, B, C ... Z がある。
- A に対して処理を依頼(リクエスト) すると、必要に応じて、A → B → C → ... → Z へとリクエストは転送される。
という設計です。
Chain of Responsibility は、日本語的に発音すると「チェイン・オブ・レスポンシビリティ」となります。
意味は「責任の連鎖」ですね。
関連記事 :
Command
Command パターンとは、
- 「処理の依頼(リクエスト)」と「処理の実行」を分離する
という設計です。
これにより、
- 処理の リクエスト はしたけど、処理の 実行 は遅らせる
- リクエスト単位で、処理のアンドゥ(元に戻す) 機能を実現する
- 処理の リクエスト は複数のサブスレッドからでも OK
ただし、処理の 実行 は単一のスレッド上で実行させたい
といったことが可能になります。
Command は、日本語的に発音すると「コマンド」となります。
意味は「命令」ですね。
関連記事 :
Interpreter
Interpreter パターンとは、
- ある分野に特化したコンピュータ言語
を実装するための設計です。
「ある分野に特化したコンピュータ言語」のことを
とも言います。
例えば、データベースの問い合わせに特化した SQL などです。
Interpreter は、日本語的に発音すると「インタープリター」もしくは「インタプリタ」となります。
意味は「解釈する人」ですね。
関連記事 :
Iterator
Iterator パターンとは、
- ある要素の集まりがあり
- そのすべての要素に順々にアクセスする
という目的のための設計です。
Iterator は、日本語的に発音すると「イテレーター」となります。
意味は「反復子」ですね。
関連記事 :
Mediator
Mediator パターンとは、
- 相互に依存する複数のクラスがある場合に
- 仲介者をはさむことで、その依存関係をシンプルにする
という設計です。
Mediator は、日本語的に発音すると「メディエーター」となります。
意味は「仲介者」ですね。
関連記事 :
Memento
Memento パターンとは、
- オブジェクトの 非公開(private) な内部状態を保存・復元する
という目的のための設計です。
Memento は、日本語的に発音すると「メメント」となります。
意味は「思い出の品」や「形見」ですね。
関連記事 :
Observer
Observer パターンとは、
- イベントを通知するクラスがあり
- そのクラスの 変更なし で、イベントを受け取りたいクラスを増やす(拡張する)
という目的のための設計です。
もう少し簡単にいうと、
- イベントを 不特定多数 のオブジェクトに通知する
という設計です。
また、依存関係の 向きを逆転 させるテクニックとしても使えます。
Observer は、日本語的に発音すると「オブザーバー」となります。
意味は「監視者」ですね。
関連記事 :
State
State パターンとは、
- オブジェクトの状態を「振る舞いを持たせたクラスオブジェクト」で表す
- それにより if や switch などの条件式を減らす
という設計です。
State は、日本語的に発音すると「ステート」となります。
意味は「状態」ですね。
関連記事 :
Strategy
Strategy パターンとは、
- ある1つのクラスがあり
- そのクラスの変更なしで、処理の一部を動的に切り替える
という目的のための設計です。
Strategy は、日本語的に発音すると「ストラテジー」となります。
意味は「戦略」ですね。
関連記事 :
Template Method
Template Method パターンは、
- 大まかな処理はベースクラスで共通化
- 具体的な処理はサブクラスで実装
という設計です。
大まかな処理は共通化して、処理の一部をサブクラスごとに切り替えたい、というときに便利です。
Template Method は、日本語的に発音すると「テンプレート・メソッド」となります。
意味は … 日本語訳しにくいですが「メソッドのひな型」でしょうか。
関連記事 :
Visitor
Visitor パターンとは、
- ある複数の異なるクラスがあり
- それらのクラスの変更なしで一連の処理を拡張する
という目的のための設計です。
また、複数の異なるクラスに対して、横断的に (for文などで) 処理したいときに便利です。
Visitor は、日本語的に発音すると「ビジター」となります。
意味は「訪問者」ですね。
関連記事 :
まとめ
本記事では、GoF によって定義された23種類のデザインパターンをざっくりとご紹介しました。
デザインパターンを理解すれば、きっと設計の補助として役立つことでしょう。
ぜひ、有効に活用したいですね。
関連記事
- 標準APIにならう命名規則
- コメントが少なくて済むコードを目指そう
- シングルトン・パターンの乱用はやめよう
- メソッドのパラメータ(引数)は使う側でチェックしよう
- 不変オブジェクト(イミュータブル) とは
- 依存性の注入(DI)をもっと気軽に
- 不要になったコードはコメントアウトで残さずに削除しよう
- 簡易的な Builder パターン
- 読み取り専用(const) のインタフェースを作る
- 図解/デザインパターン一覧 (GoF)
- Abstract Factory パターン
- Adapter パターン
- Bridge パターン
- Builder パターン
- Chain of Responsibility パターン
- Command パターン
- Composite パターン
- Decorator パターン
- Facade パターン
- Factory Method パターン
- Flyweight パターン
- Interpreter パターン
- Iterator パターン
- Mediator パターン
- Memento パターン
- Observer パターン
- Prototype パターン
- Proxy パターン
- Singleton パターン
- State パターン
- Strategy パターン
- Template Method パターン
- Visitor パターン