Rubyデザインパターン備忘録

目次

概要

Rubyデザインパターンまとめに記載されている各デザインパターンの概要をまとめる。

デザインパターンのポイント

GoFデザインパターンには下のプリンシパルがあります。

  • 変わるものを変わらないものから分離する
  • インタフェースに対してプログラミングし、実装に対して行わない
  • 継承より集約
  • 委譲、委譲、委譲
  • 必要になるまで作るな(You Ain’t Gonna Need It./YAGNI)

デザインパターン一覧

アブストラクトファクトリ(Abstract Factory)

  • 矛盾のないオブジェクトの組み合わせを作る

ビルダ (Builder)

  • オブジェクトの生成に大量のコードが必要
  • オブジェクトを作り出すのが難しい
  • オブジェクト生成時に必要なチェックを行いたい

ファクトリメソッド

  • インスタンスの生成をサブクラスに任せるパターンです。
  • インスタンスの生成部分を切り離すことで、結合度を下げて追加・変更・保守を容易にします。

シングルトンパターン(Singleton)

  • 1つだけに限定されたインスタンスを複数のオブジェクト内で共有する場合に用います。
  • たとえば、ログの書込処理を行うメソッドでのファイルへのアクセスや、システム内で共通のキャッシュテーブルを参照する場合などです。

アダプタ(Adapter)

  • アダプタとは現実世界の変換コネクタのようなものです。
  • 直接つながらないコネクタと差込口は、それらの間を変換コネクタが結び付けます。
  • コネクタと差込口にカスタマイズが不要な点がアダプタの利点です。
  • 関連性・互換性のないオブジェクトどうしを結び付ける必要があります

コンポジット(Composite)

  • 「全体〜部分」(個別のオブジェクトと合成したオブジェクト)を同一のものとしてとらえることで、再帰的な構造をクラスで表現する
  • 「全体〜部分」は同じインタフェースを継承します。
  • ファイルシステムなどの木構造を伴う再帰的なデータ構造を表現できる
  • 階層構造で表現されるオブジェクトの取扱いを楽にする
  • ディレクトリとフォルダを同様のコンポーネントとして扱うことで、削除処理などを再帰的に行えるようにできる

デコレータ(Decorator)

  • 既存のオブジェクトに対して簡単に機能の追加をするためのパターンです。
  • デコレータパターンを使うと、レイヤ状に機能を積み重ねて、必要な機能をもつオブジェクトを作ることができます。
  • 既存のオブジェクトの中身を変更することなく、機能を追加できる
  • 組み合わせでさまざまな機能を実現できる
  • 継承よりも変更の影響を限定しやすい

プロキシ(Proxy)

  • 1つのオブジェクトに複数の関心ことがある場合にそれを分離するために用います。
  • たとえば、オブジェクトの本質的な目的とは異なる「セキュリティ要件やトランザクション管理など」を切り離して実装できます。
  • プロキシには次の3つの種類があります。
    • 防御Proxy
    • 仮想Proxy
    • リモートProxy

コマンド(Command)

  • あるオブジェクトに対してコマンドを送ることでそのオブジェクトのメソッドを呼び出すことです。
  • たとえば、ファイルシステムの実装は知らなくてもユーザーはファイルの追加、削除といったコマンドを実行できます。
  • コマンドの変更・追加・削除に対して柔軟になる

インタプリタ(Interpreter)

  • ひとつひとつの問題はシンプルだが、組み合わさって複雑になるような場合に効果を発揮します。
  • 専用の言語を作り、その言語で得られた手順にもとづいて処理を実行していく

イーテレータ

  • 要素の集まったオブジェクト(配列など)にアクセスする
  • 集合の要素に順にアクセスする必要がある
  • 要素の集まりをもつオブジェクトの各要素に、順番にアクセスする方法を提供するためのデザインパターンです。

オブザーバ(Observer)

  • オブジェクトの状態が変化する可能性がある
  • 変化したことをほかのオブジェクトに通知する必要がある
  • 例としては、Aで起きたイベントをB, Cが知る必要がある場合などです。
  • オブジェクト間の依存度を下げることができる
  • 通知先の管理をオブザーバが行うことで、サブジェクトは通知側を意識しなくていい

ストラテジ(Strategy)

  • たとえば5ステップの中の3ステップが異なったAとBがあり、このAとBをスイッチしたい時に使えるパターンです。
  • 使用するアルゴリズムに多様性を持たせることができる
  • コンテキストと戦略を分離することでデータも分離できる
  • 継承よりもストラテジを切り替えるのが楽

テンプレートメソッド(Template Method)

  • 2つのコードのやりたいこと(アルゴリズム)がほとんど同じで、ある一部だけ変えたいようなパターンのときに有効です。
  • 抽象的なベースのクラス側に、「変わらない基本的なアルゴリズム」を置ける
  • 抽象的なベースのクラスは「高レベルの処理」を制御することに集中できる
  • サブクラス側に、「変化するロジック」を置ける
  • サブクラスは「詳細を埋めること」に集中できる
  • 「高レベルの処理」とは、プログラミング的には「抽象度の高い処理、ロジック的な部分、処理のフレーム」といった言葉に言い換えられると思います。
  • 「詳細を埋める」とは、プログラム的にはレポートの行を書き出すといった具体的な処理を指しています。