この記事は『Head Firstデザインパターン』の内容を自分なりにメモしたものです。 サンプルコードをrubyで書き換えたりしているので、玄人の方はぜひコメントを!! 僕のように初級者で気になった方はぜひ書籍の方を確認してみてください^^
コーヒーショップのシステム
そのコーヒーショップのメニューがとても少なければいいと思うのですが、たいていのコーヒーショップはトッピングの追加や細かいオプションの追加ができたりします。
最初の設計
継承元のフィールドにトッピングを入れる?入れないのBool値を持たせて、料金を計算する。
問題の発生
あたらしいトッピングが追加されるとどうする? トッピング2倍で!というケースに対応できない
Decoratorパターンで実装しなおす
トッピングがBeverageのフィールドを持って、自身のコストのみを追加する。
Rubyで書いた場合はこんな感じ
class Beverage def get_description raise "should implement get_description method" end def cost raise "should implement cost method" end end class CondimentDecorator < Beverage end class Espresso < Beverage def initialize @description = "エスプレッソ" end def get_description @description end def cost 200 end end class HouseBlend < Beverage def initialize @description = "ハウスブレンドコーヒー" end def get_description @description end def cost 150 end end class Mocha < CondimentDecorator def initialize beverage @beverage = beverage end def get_description "#{@beverage.get_description}, モカ" end def cost 50 + @beverage.cost end end
実行コードは以下
beverage = Espresso.new puts "#{beverage.get_description}: #{beverage.cost}円" #=> エスプレッソ: 200円 beverage = Mocha.new(beverage) beverage = Mocha.new(beverage) beverage = Mocha.new(beverage) puts "#{beverage.get_description}: #{beverage.cost}円" #=> エスプレッソ, モカ, モカ, モカ: 350円
Decoratorパターンの定義・特徴
デコレータパターンはオブジェクト上に付加的な責務を動的に付与します。デコレータは、サブクラス化の代替となる。柔軟な機能拡張手段を提供します。
一つのクラスを継承し、メインとオプションの方向で役割がわかれている
なんか再帰っぽいイメージ、メインの方は明確に返す値(最低限の値)を持っていて、オプションの方は自分が持ってるベースクラスを元にした返り値をもってる。
使い勝手の良さそうなパターンだなと思いました。
昔とても疑問に思っていたJavaのI/O周りの定型コード
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
ここらへんもデコレータパターンを使っているということを知って、なるほどと感じました。。。
参考文献

Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本
- 作者: Eric Freeman,Elisabeth Freeman,Kathy Sierra,Bert Bates,佐藤直生,木下哲也,有限会社福龍興業
- 出版社/メーカー: オライリージャパン
- 発売日: 2005/12/02
- メディア: 大型本
- 購入: 14人 クリック: 362回
- この商品を含むブログ (98件) を見る