技術とか戦略とか

IT技術者が技術や戦略について書くブログです。

Gofのデザインパターンの自分なりのまとめ

増補改訂版Java言語で学ぶデザインパターン入門」という本でGofデザインパターンを勉強しました。
自分の知識の整理も兼ねて、どのようなデザインパターンが存在し、どのような場合に適用できるのかを簡単にまとめたいと思います。
 
なお、この本とほぼ同様のことが以下のページで紹介されています。
 
デザインパターン  TECHSCORE(テックスコア)

http://www.techscore.com/tech/DesignPattern/index.html/
 
00.デザインパターン 概論
 ・デザインパターンとは何か
  オブジェクト指向言語における設計のパターン集。
  良く出会う問題とその解決法となる設計を名前をつけてまとめたもの。
  
 ・デザインパターンを用いるメリットとは何か
  変更に対する影響箇所が少なくなる設計を行う上でのヒントとなる。
  また、開発者間でのコミュニケーションがスムーズになる。
  (「このクラスを作って、クラス間の…」が「○○パターンにしよう」になる)
  
01.Iterator パターン
 ・何を意図した設計なのか
  複数の要素を順番に取り出すためのクラスを作成する。
  (Javaで標準で用意されているIteratorもこのパターンを利用している)
  
 ・どのような場合に有効なのか
  複数の要素に対して決められた順番で処理する必要がある場合。
  
02.Adapter パターン
 ・何を意図した設計なのか
  他システムのインターフェースと自システムの架け橋となるクラスを作成する。
  (アダプタのように変換を行う)
  
 ・どのような場合に有効なのか
  他システムのインターフェースに合わせる必要がある場合。
  
03.TemplateMethod パターン
 ・何を意図した設計なのか
  処理の概要を抽象クラス、具体的な処理内容を具象クラスに記述する。
  (抽象クラスがテンプレートとなる)
  
 ・どのような場合に有効なのか
  似たような処理をいくつも実装する場合。
  
04.FactoryMethod パターン
 ・何を意図した設計なのか
  処理の概要を抽象クラス、具体的な処理内容を具象クラスに記述する。
  オブジェクトを生成するクラスとそのオブジェクトを使用するクラスに分ける。
  (オブジェクトを生成するクラスはFactoryと呼ばれる)
  
 ・どのような場合に有効なのか
  利用するオブジェクトに頻繁に変更が入る場合。
  複数のオブジェクトを利用する場合。
  
05.Singleton パターン
 ・何を意図した設計なのか
  インスタンスが絶対に一個しか作成されないようなクラスを作成する。
  
 ・どのような場合に有効なのか
  インスタンスが複数存在すると制御が困難になるクラスを作成する場合。
  
06.Prototype パターン
 ・何を意図した設計なのか
  処理の概要を抽象クラス、具体的な処理内容を具象クラスに記述する。
  処理を利用するクラスには抽象クラスを使わせる。
  インスタンスを作成する場合は既存のインスタンスをコピーする。
  (既存のインスタンスがプロトタイプとなる)
  
 ・どのような場合に有効なのか
  処理の種類が多く一つのクラスにまとめられない場合。
  複雑な処理過程があり、クラスからインスタンスを一から生成するのが難しい場合。
  インスタンス生成のフレームワークで具体的なクラス名を指定したくない場合。
  
07.Builder パターン
 ・何を意図した設計なのか
  処理の概要を抽象クラス、具体的な処理内容を具象クラスに記述する。
  処理を利用するクラスには抽象クラスを使わせる。
  抽象クラスのメソッドを利用し、組み上げることで、複雑なものを作成する。
  
 ・どのような場合に有効なのか
  大きな構造を持ったものを段階的に組み上げたい場合。
  
08.AbstractFactory パターン
 ・何を意図した設計なのか
  大きな構造を持ったものを作るのに必要な部品をクラスとして定義する。
  部品を表すクラスのオブジェクトを生成するクラスも作成する。
  これらのクラスを抽象クラスと具象クラスに分ける。
  
 ・どのような場合に有効なのか
  抽象クラス(API)を柔軟に組み合わせて大きな構造を組み立てたい場合。
  
09.Bridge パターン
 ・何を意図した設計なのか
  機能を実装するクラスと、機能を利用するクラスに分ける。
  機能を利用するクラスは、実際の処理を機能を実装するクラスに委譲する。

  (橋渡し)
  これらのクラスは抽象クラスと具象クラスに分ける。
  
 ・どのような場合に有効なのか
  頻繁な機能追加が予想される場合。
  
10.Strategy パターン
 ・何を意図した設計なのか
  問題を処理するロジック(戦略)について、抽象クラスと具象クラスに分ける。
  ロジックを使って問題を解くクラスには抽象クラスを使わせる。
  
 ・どのような場合に有効なのか
  問題を処理するロジックが複数通り存在する場合。
  
11.Composite パターン
 ・何を意図した設計なのか
  葉となるクラスと、葉や容器を格納する容器となるクラスを作成する。
  これらのクラスについて抽象クラスを作成する。
  
 ・どのような場合に有効なのか
  ディレクトリ構造のように入れ子になっている場合。
  
12.Decorator パターン
 ・何を意図した設計なのか
  葉となるクラスと、葉や容器を格納する容器となるクラスを作成する。
  容器となるクラスには、葉となるクラスを飾りつける処理を含める。
  (容器となるクラスは、抽象クラスと具象クラスに分ける)
  葉となるクラスと容器となるクラスの抽象クラスも作成する。
  
 ・どのような場合に有効なのか
  ある要素を飾り付けるための処理を複数実装したい場合。
  (文字列に対して、別の文字列をどんどん付け加えていく等)
  
13.Visitor パターン
 ・何を意図した設計なのか
  Compositeパターン等で作成したデータ構造に対して処理を行うクラスを実装する。
  (データ構造に対して処理を行うクラスがVisitorに相当する)
  
 ・どのような場合に有効なのか
  あるデータ構造に対して処理を行う場合。
  
14.ChainOfResponsibility パターン
 ・何を意図した設計なのか
  問題を処理するロジックについて、抽象クラスと具象クラスに分ける。
  抽象クラスは自らのクラスへの委譲を行う。
  これで、ある具象クラスで解決できない場合に他の具象クラスを使うことができる。
  (責任のたらい回し)
  
 ・どのような場合に有効なのか
  問題を処理するロジックに独立性を持たせたい場合。
  (問題が解決できなかった場合の処理まで持たせたくない場合)
  
15.Facade パターン
 ・何を意図した設計なのか
  複数のクラスを適切な順番で組み合わせる窓口クラスを作成する。
  機能を利用するクラスには窓口クラスを利用させる。
  
 ・どのような場合に有効なのか
  機能を利用する側に複雑な処理を見せたくない場合。
  
16.Mediator パターン
 ・何を意図した設計なのか
  具体的な処理を行う複数のクラスと、それらのクラスの抽象クラスを作成する。
  また、それらのクラスの調停を行うクラスも作成する。
  調停クラスも抽象クラスと具象クラスに分ける。
  
 ・どのような場合に有効なのか
  具体的な処理を行う複数のクラスの処理が複雑に絡み合う場合。
  (例:チェックボックスで○○が選択されたらメッセージボックスを不活性化)
  
17.Observer パターン
 ・何を意図した設計なのか
  状態を観察するクラスと、状態の変化に合わせて処理を行うクラスに分ける。
  観察するクラスは状態の変化の検知後、処理を行うクラスのメソッドを実行する。
  
 ・どのような場合に有効なのか
  状態の変化に合わせて処理を行う必要がある場合。
  
18.Memento パターン
 ・何を意図した設計なのか
  状態を保存するクラスを作成する。
  (ゲームで言うセーブデータ(記録)をクラスとして用意する)
  
 ・どのような場合に有効なのか
  状態を保存して、その状態に戻れるようにしたい場合。
  
19.State パターン
 ・何を意図した設計なのか
  「昼間」「夜間」等の状態について、それらの状態毎にクラスを作成する。
  (状態を表すクラスの抽象クラスも作成する)
  
 ・どのような場合に有効なのか
  状態が多く、状態に応じて複雑なロジック実装が必要な場合。
  
20.Flyweight パターン
 ・何を意図した設計なのか
  メモリ等のリソースの無駄を省くことを意図する。
  オブジェクトが生成済みなら再びオブジェクトが生成されないようにする。
  それを実現するためのFactoryクラスを作成する。
  
 ・どのような場合に有効なのか
  一つのオブジェクトを使い回すことでリソース節約が可能な場合。
  
21.Proxy パターン
 ・何を意図した設計なのか
  重い処理を行うクラスが存在する場合に負荷を下げることを意図する。
  極力そのクラスを使わなくても済むようにするため、代理の軽いクラスを作成する。
  これらのクラスは、同一視できるように抽象クラスでまとめる。
  
 ・どのような場合に有効なのか
  思い処理を行うクラスが存在し、そのクラスの代役を作ることが可能な場合。
  
22.Command パターン
 ・何を意図した設計なのか
  複数の命令毎にクラス化し、それらの命令クラスを束ねる抽象クラスも作成する。
  命令を利用するクラスは、その抽象クラスを利用する。
  命令の具象クラスは、対象物を表すクラスに対して処理を行う。
  
 ・どのような場合に有効なのか
  複数の命令が存在し、命令の追加が予想される場合。
  命令を組み合わせて別の命令を作る場合。
  
23.Interpreter パターン
 ・何を意図した設計なのか
  命令を記述するための簡単なミニ言語(設定ファイル)を作る。
  そのミニ言語を解釈するためのクラスをjavaで実装する。
  (例:終端文字を扱うクラスと非終端文字を扱うクラスを作成する)
  
 ・どのような場合に有効なのか
  javaを修正しなくても、ミニ言語を修正するだけで変更を可能としたい場合。