デザインパターンについて


デザインパターンとは

  • オブジェクト指向プログラミングにおける再利用性のある設計パターンのこと

デザインパターンの恩恵

  • 車輪の再発明を行うことなく、ベストプラクティス体得することができる
  • 再利用性の高いコードを書くことができ、結果的にオブジェクト指向プログラミングの生産性や信頼性の向上を得ることができる
  • 「よく出会う問題とそれに対処する良い設計」を知っていれば、良い設計をスムースに進めていくことができる

設計へ落とし込む際の注意点

  • あくまで、良いアイディアを与えてくれそうなものを探すに留める
    • 大切なのは、なぜこれらが良い設計とされているのかを理解すること
  • クラスの抽出時
    • デザインパターンから、抽象的な概念を取り入れる
  • 実装とインターフェースの切り分け
    • 実装に対してプログラミングを行うのではなく、インターフェースに対してプログラミングを行う
  • 再利用性を高める
    • オブジェクトコンポジション(別のオブジェクトが持つ機能を組み合わせて利用すること)を常に考える
  • 変化に強くする
    • あらかじめ起こりうる追加や変更を想定しておく必要がある
    • デザインパターンは、想定される仕様の追加や変更に柔軟に対応できる方法を教えてくれる
  • 必要になるまで作るな(YAGNI/You Ain't Gonna Need It.)
    • 将来的に必要になるかも?を欲して複雑になってしまわないように
    • デザインパターンは手段であり、目的ではない

デザインパターンの種類

「オブジェクト指向における再利用のためのデザインパターン(GOF)」から参照。

オブジェクトの生成に関するパターン

Abstract Factory

  • インスタンスの生成を専門に行うクラスを用意することで、整合性を必要とされる一連のオブジェクト群を間違いなく生成するためのパターン
  • Factoryクラスを切り替えることでインスタンスを切り替えることができる

Builder

  • 同じ作成過程で異なる表現形式の結果を得るためのパターン
  • オブジェクトの生成過程をより柔軟にする際に利用できる

Factory Method

  • インスタンスの生成をサブクラスに行わせることで、より柔軟に生成するインスタンスを選択することが可能
  • 機能が複雑になりクラスが多くなった際などにも利用できる

Prototype

  • プロトタイプからインスタンスを生成することができるようにするためのパターン
  • 同じクラスで複数のオブジェクトを作成する際に利用できる

Singleton

  • オブジェクトの唯一性を保証するためのパターン
  • 他クラスから新たにインスタンスが生成されないように制御する際に利用できる

プログラムの構造に関するパターン

Adapter

  • インタフェースに互換性の無いクラス同士を組み合わせることを目的としたパターン
  • 本来繋がっていないクラス同士を関連づける時など、利用したいインタフェースを強制的に変えたいような場合に利用できる

Bridge

  • 機能と実装を分離して、それぞれを独立に拡張することができるようにするためのパターン
  • 機能の上位クラスが、集約している実装の上位クラスに処理を委譲することによって、2つの階層を橋のように結びつけることができる

Composite

  • 器と中身を同一視することで、再帰的な構造の取り扱いを容易にすることができるパターン

Decorator

  • 飾り枠と中身を同一視することで、より柔軟な機能拡張方法を提供することができるパターン
  • 継承以外の手段で機能を追加することができる

Facade

  • 既存のクラスを複数組み合わせて使う手順を、「窓口」となるクラスを作ってシンプルに利用できるようにするパターン

Flyweight

  • 同じインスタンスを共有することで無駄なを生成を削減し、プログラム全体を軽くすることを目的としたパターン
  • 小さなオブジェクトを数多くロードする状況で効率的に処理できる

Proxy

  • 要求を代理人のオブジェクトが受け取り、処理をするようなパターン

オブジェクトの振る舞いに関するパターン

Chain of Responsibility

  • 責任者を鎖状につないでおき、いずれかの段階で、「誰か」が処理をすることを表現するようなパターン
  • メッセージを他のクラスのオブジェクトに送って処理することが可能

Command

命令を表すオブジェクトをメソッドの引数にすることで、1つの引数で複数のデータと処理を伝えることができるパターン

Interpreter

インターフェースを使って、構文解析の結果をツリー構造で表示するパターン

Iterator

  • 要素の集まりを保有するオブジェクトの各要素に順番にアクセスする方法を提供するためのパターン
  • 集約オブジェクトの種類や実装に依存しない、統一的な走査方法を提供したいような場合に利用できる

Mediator

  • 適宜判断を行い指示を出す「仲裁人」の役割を果たすクラスを利用するパターン
  • クラス間の疎結合を綺麗に整理することができ、複数のオブジェクトを組み合わせて機能を実装する際に利用できる

Memento

  • 必要な情報のみを保持しておき、必要なデータのみを復元できるようなパターン

Observer

  • 通知の仕組みをより汎用的に利用できる形で提供するためのパターン
  • あるオブジェクトの変化を別のオブジェクトに通知させることが可能

State

  • モノではなく、「状態」をクラスとして表現するパターン
  • if文を利用することなく、状態に対応した処理を行うことができる

Strategy

  • 戦略の部分を意識して別クラスとして作成することで、柔軟でメンテナンスしやすい設計をするためのパターン
  • クラスを使う人のコードを変更することなくアルゴリズムを変更することが可能

Template Method

  • テンプレートの機能を持つクラスを作成するパターン
  • 処理の流れをテンプレート化したいような時に利用できる

Visitor

  • 受け入れる側に処理を追加することなく、処理を追加することができるパターン
  • オブジェクトに動的に機能を追加するために利用できる