LoginSignup
2
0

More than 5 years have passed since last update.

【デザインパターン】 Decoratorパターン

Last updated at Posted at 2015-06-15

概要

既存のオブジェクトに新しい責任を動的に追加するパターン

以下の4種類のクラスからなる
1. Componentクラス(責任を動的に追加できるオブジェクトのためのインターフェイスを定義)
2. ConcreteComponentクラス(責任を動的に追加できる具体的なオブジェクトを定義)
3. Decoratorクラス(オブジェクトへの参照を保持し、1.と一致したインターフェイスを定義)
4. ConcreteDecoratorクラス(2.で定義されたオブジェクトに責任を追加するオブジェクトを定義)

具体例と実装

コーヒーを例にすると

上記1~4はそれぞれ
1. コーヒークラス(Coffeeクラス)
2. アイスコーヒークラス(IcedCoffeeクラス)
3. コーヒートッピングクラス(CoffeeToppingDecoratorクラス)
4. 生クリームトッピングクラス、キャラメルトッピングクラス(CreamDecorator、CaramelDecoratorクラス)

が対応する。
コードの詳細は以下

coffeerb
class Coffee
  def initialize(strength, volume)
    @strength = strength
    @volume = volume
  end

  def taste
  end

  def flavor
  end
end
iced_coffee.rb
class IcedCoffee < Coffee
  def initialize(strength, volume)
    super
  end

  def taste
    # スッキリした味わい
  end

  def flaver
    # さっぱりしたフレーバー
  end
end
coffee_topping_decorator.rb
class CoffeeToppingDecorator
  def initialize(coffee)
    @coffee = coffee
  end

  def taste
    @coffee.taste
  end

  def flavor
    @coffee.flavor
  end
end
cream_decorator.rb
class CreamDecorator < CoffeeToppingDecorator
  def taste
    # @coffee.tasteにコクを追加
  end
end
caramel_decorator.rb
class CaramelDecorator < CoffeeToppingDecorator
  def flavor
    # @coffee.flavorに甘い香りを追加
  end
end
client.rb
caramel_cafe_au_lait = CaramelDecorator.new(CreamDecorator.new(IcedCoffee.new('濃い目', '普通サイズ')))
calamel_cafe_au_lait.taste # スッキリ、コクがある
calamel_cafe_au_lait.flavor # さっぱり、甘い香り

メリット

  • 責任の削除や追加が容易であるため、オブジェクトに複数の独立した責任を持たせたい場合に便利
  • 動的に責任を追加できるため、責任ごとに多数の依存関係のあるクラスを作成しなくて良い
  • 単純な部品を複数組み合わせてオブジェクトの機能を組み立てられるため、複雑なクラスを作成した場合に比べてアプリケーションが不要な機能を取り込む必要がなくなる上、予期せぬ機能追加にも対応しやすい

まとめ

たくさんの機能を組み合わせたオブジェクトを作成する際に便利なパターン
動的な機能拡張や予期せぬ機能追加が予想される場合に用いる

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0