読者です 読者をやめる 読者になる 読者になる

初心者にも分かるデザインパターン

デザインパターンを始めて学ぶ方、過去に取り組んだが挫折してしまった方を念頭に、分かりやすくデザインパターンを説明します。

(序1) デザインパターンとは?

当ブログのデザインパターンでは、書籍「オブジェクト指向における再利用のためのデザインパターン(通称:GoF本)」で紹介されている23個のパターンを、初めて取り組む方にも理解できることを目指して、出来るだけ噛み砕いて解説したいと考えております。

デザインパターンとは?

デザインパターン優秀なエンジニアが編み出した設計上のノウハウをパターンとして取りまとめたものです。

デザインパターンを覚えるメリット

1. 「オブジェクト指向」の理解の助けになる
継承や多態性、インタフェースなど、オブジェクト指向言語特有の仕組みを、「なんとなく」ではなく、きちんと理解できるようになります。
特にCOBOLC言語など、手続き型言語出身のエンジニアにとっては、デザインパターンの習得が、手続き型からオブジェクト指向への発想の転換への近道だと考えています。
2. よい設計のアイデアが広がる
デザインパターンを習得すると、設計のアイデアが確実に広がり、より良い設計ができるようになります。一流のエンジニアを目指すのであれば(一流のエンジニアを目指すのではなくてもプロを自称するのであれば)、デザインパターンの習得は避けては通れないでしょう。

では、実際のところ、どれだけのエンジニアが「デザインパターン」を習得しているのでしょうか?
正確なことは分かりませんが、デザインパターンを習得しているエンジニアの方が少数であるのは間違い無いでしょう。多くのエンジニアがデザインパターン(の存在すら)を知らずに設計を行っているわけです。それでも設計者としてなんとなく仕事が出来るのは以下の理由であると私は認識しています。

1. フレームワークを用いた開発が前提
多くのプロジェクトでは、フレームワークを用いた開発が前提になっております。したがって、フレームワークの適用範囲においては、フレームワークのルールに従い、設計を行うことになります。デザインパターンなどの知識がなくても、ある程度正しい設計が行えるようになっています。
⇒ フレームワークの適用範囲内でしか正しい設計が行えない設計者ではなく、どのような条件でも、堅牢なシステムを構築できる「プロのエンジニア」としてやっていきたいのであれば、「デザインパターン」の習得は必要です。

2. 設計の良し悪しがあまり問われない
多くのプロジェクトでは、仕様通り正しく動作するがどうかには注目していますが、保守しやすい堅牢なシステムかどうかは、要望はあっても、測定する術がないので、二の次になってしまうのが多いのではないかと思います。デザインパターンを知ってなくても、一応、仕様通り正しく動作するシステムは設計できます。
⇒ 正しく動作するシステムの設計を行えるかもしれませんが、堅牢なシステムを構築できる「プロのエンジニア」としてやっていきたいのであれば、「デザインパターン」の習得は必要です。
  

デザインパターンGoF)一覧

当ブログで紹介するGoFデザインパターンの一覧を下記に記載いたします。大きくは
・ 生成に関するパターン
・ 構造に関するパターン
・ 振る舞いに関するパターン
に分類されます。

引用元: オブジェクト指向における再利用のためのデザインパターン
  

生成に関するパターン

パターン名 説明
Factory Method オブジェクトを生成するときのインタフェースだけを規定して、実際にどのクラスをインスタンス化するかはサブクラスが決めるようにする。Factory Methodパターンは、インスタンス化をサブクラスに任せる。
Abstract Factory 互いに関連したり依存し合うオブジェクト群を、その具象クラスを明確にせずに生成するためのインタフェースを提供する。
Builder 複合オブジェクトについて、その作成過程を表現形式に依存しないものにすることにより、同じ作成過程で異なる表現形式のオブジェクトを生成できるようにする。
Prototype 生成すべきオブジェクトの種類を原型となるインスタンスを使って明確にし、それをコピーすることで新たなオブジェクトの生成を行う。
Singleton あるクラスに対してインスタンスが1つしか存在しないことを保証し、それにアクセスするためのグローバルな方法を提供する。

  

構造に関するパターン

パターン名 説明
Adapter あるクラスのインタフェースを、クライアントが求める他のインタフェースへ変換する。Adapterパターンは、インタフェースに互換性のないクラス同士を組み合わせることができるようにする。
Bridge 抽出されたクラスと実装を分離して、それらを独立に変更できるようにする。
Composite 部分―全体階層を表現するために、オブジェクトを木構造に組み立てる。Compositeパターンにより、クライアントは、個々のオブジェクトとオブジェクトを合成したものを一様に扱うことができるようになる。
Decorator オブジェクトに責任を動的に追加する。Decoratorパターンは、サブクラス化よりも柔軟な機能拡張方法を提供する。
Facade サブシステム内に存在する複数のインタフェースに1つの統一インタフェースを与える。Facadeパターンはサブシステムの利用を容易にするための高レベルインタフェースを定義する。
Flyweight 多数の細かいオブジェクトを効率よくサポートするために共有を利用する。
Proxy あるオブジェクトへのアクセスを制御するために、そのオブジェクトの代理、または入れ物を提供する。

  

振る舞いに関するパターン

パターン名 説明
Command 要求をオブジェクトとしてカプセル化することによって、異なる要求や、要求からなるキューやログにより、クライアントをパラメータ化する。また、取り消し可能なオペレーションをサポートする。
Chain of Responsibility 1つ以上のオブジェクトに要求を処理する機会を与えることにより、要求を送信するオブジェクトと受信するオブジェクトの結合を避ける。受信する複数のオブジェクトをチェーン状につなぎ、あるオブジェクトがその要求を処理するまで、そのチェーンに沿って要求を渡していく。
Interpreter 言語に対して、文法表現と、それを使用して文を解釈するインタプリタを一緒に定義する。
Iterator 集約オブジェクトが基にある内部表現を公開せずに、その要素に順にアクセスする方法を提供する。
Mediator オブジェクト群の相互作用をカプセル化するオブジェクトを定義する。Mediatorパターンは、オブジェクト同士がお互いを明示的に参照し合うことがないようにして、結合度を低めることを促進する。それにより、オブジェクトの相互作用を独立に変えることができるようになる。
Memento カプセル化を破壊せずに、オブジェクトの内部状態を捉えて外面化しておき、オブジェクトを後にこの状態に戻すことができるようにする。
Observer あるオブジェクトが状態を変えたときに、それに依存するすべてのオブジェクトに自動的にそのことが知らされ、また、それらが更新されるように、オブジェクト間に一対多の依存関係を定義する。
State オブジェクトの内部状態が変化したときに、オブジェクトが振る舞いを変えるようにする。クラス内では、振る舞いの変化を記述せず、状態を表すオブジェクトを導入することでこれを実現する。
Strategy アルゴリズムの集合を定義し、各アルゴリズムカプセル化して、それらを交換可能にする。Strategyパターンを利用することで、アルゴリズムを、それを利用するクライアントからは独立に変更することができるようになる。
Template Method 1つのオペレーションにアルゴリズムのスケルトンを定義しておき、その中のいくつかのステップについては、サブクラスでの定義に任せることにする。Template Methodパターンでは、アルゴリズムの構造を変えずに、アルゴリズム中のあるステップをサブクラスで再定義する。
Visitor あるオブジェクト構造上の要素で実行されるオペレーションを表現する。Visitorパターンにより、オペレーションを加えるオブジェクトのクラスに変更を加えずに、新しいオペレーションを定義することができるようになる。