Rubyによるデザインパターンまとめ : factory
- 作者: Russ Olsen,ラス・オルセン,小林健一,菅野裕,吉野雅人,山岸夢人,小島努
- 出版社/メーカー: ピアソン桐原
- 発売日: 2009/04/01
- メディア: 単行本
- 購入: 13人 クリック: 220回
- この商品を含むブログ (66件) を見る
利用する場面
あるオブジェクトについて、ある場合にはa,b,cというクラスを利用したく、別の場合にはx,y,zというクラスを利用したい場合。
あれこれ
- factoryパターンとは、template methodパターンをクラスの選択(及びインスタンスの生成)に関して適用した場合の呼び名。
- すなわち、サブクラスを用意してサブクラスの中でそれぞれ適切なクラスを選択して利用する。
- abstract factoryパターンとは、strategyパターンをクラスの選択(及びインスタンスの生成)に関して適用した場合の呼び名。
サンプル
factoryパターンから。
class Dinner attr_reader :food, :drink def initialize new_food new_drink end end class Sushi ; end class Steak ; end class Sake ; end class Wine ; end class JapaneseDinner < Dinner def new_food @food = Sushi.new end def new_drink @drink = Sake.new end end class WesternDinner < Dinner def new_food @food = Steak.new end def new_drink @drink = Wine.new end end j = JapaneseDinner.new p j.food # => #<Sushi:0x007fee07832438> p j.drink # => #<Sake:0x007fee07832410> w = WesternDinner.new p w.food # => #<Steak:0x007fee07831e98> p w.drink # => #<Wine:0x007fee07831e70>
続いてabstract factoryパターン。
class Dinner attr_reader :food, :drink def initialize(dish_factory) @dish_factory = dish_factory @food = @dish_factory.new_food @drink = @dish_factory.new_drink end end class Sushi ; end class Steak ; end class Sake ; end class Wine ; end class JapaneseDishFactory def new_food Sushi.new end def new_drink Sake.new end end class WesternDishFactory def new_food Steak.new end def new_drink Wine.new end end j = Dinner.new(JapaneseDishFactory.new) p j.food # => #<Sushi:0x007fc075078e00> p j.drink # => #<Sake:0x007fc075078dd8> w = Dinner.new(WesternDishFactory.new) p w.food # => #<Steak:0x007fc0750789c8> p w.drink # => #<Wine:0x007fc0750787e8>
個々のabstract factoryをクラスにせず、インスタンスにしてもよい。
class Dinner attr_reader :food, :drink def initialize(dish_factory) @dish_factory = dish_factory @food = @dish_factory.new_food @drink = @dish_factory.new_drink end end class Sushi ; end class Steak ; end class Sake ; end class Wine ; end class DishFactory def initialize(food, drink) @food = food @drink = drink end def new_food @food.new end def new_drink @drink.new end end japanese_dish_factory = DishFactory.new(Sushi, Sake) j = Dinner.new(japanese_dish_factory) p j.food # => #<Sushi:0x007fc075078e00> p j.drink # => #<Sake:0x007fc075078dd8> western_dish_factory = DishFactory.new(Steak, Wine) w = Dinner.new(western_dish_factory) p w.food # => #<Steak:0x007fc0750789c8> p w.drink # => #<Wine:0x007fc0750787e8>