「Rubyによるデザインパターン」の読書メモです。
パラメータ化された Factory Method パターン
class Duck
def initialize(name)
@name = name
end
def eat
puts "アヒル #{@name} は食事中です。"
end
def speak
puts "アヒル #{@name} はガーガー鳴いています。"
end
def sleep
puts "アヒル #{@name} は静かに眠っています。"
end
end
class Frog
def initialize(name)
@name = name
end
def eat
puts "カエル #{@name} は食事中です。"
end
def speak
puts "カエル #{@name} はゲロゲロっと鳴いています。"
end
def sleep
puts "カエル #{@name} は眠りません。一晩中ゲロゲロ鳴いています。"
end
end
class Algae
def initialize(name)
@name = name
end
def grow
p "藻 #{@name} は日光を浴びて育ちます。"
end
end
class WaterLity
def initialize(name)
@name = name
end
def grow
p "睡蓮 #{@name} は浮きながら日光を浴びて育ちます。"
end
end
class Pond
def initialize(number_animals, number_plants)
@animals = []
number_animals.times do |i|
animal = new_organism(:animal, "動物#{i}")
@animals << animal
end
@plants = []
number_plants.times do |i|
plant = new_organism(:plant, "植物#{i}")
@plants << plant
end
end
def simulate_one_day
@plants.each {|plant| plant.grow}
@animals.each {|animal| animal.speak}
@animals.each {|animal| animal.eat}
@animals.each {|animal| animal.sleep}
end
end
class DuckWaterLilyPond < Pond
def new_organism(type, name)
if type == :animal
Duck.new(name)
elsif type == :plant
WaterLily.new(name)
else
raise "Unknown"
end
end
end
class FrogAlgaePond < Pond
def new_organism(type, name)
if type == :animal
Frog.new(name)
elsif type == :plant
Algae.new(name)
else
raise "Unknown"
end
end
end
pond = FrogAlgaePond.new(3, 2)
pond.simulate_one_day
具象クラスも外から渡すパターン
class Duck
def initialize(name)
@name = name
end
def eat
puts "アヒル #{@name} は食事中です。"
end
def speak
puts "アヒル #{@name} はガーガー鳴いています。"
end
def sleep
puts "アヒル #{@name} は静かに眠っています。"
end
end
class Frog
def initialize(name)
@name = name
end
def eat
puts "カエル #{@name} は食事中です。"
end
def speak
puts "カエル #{@name} はゲロゲロっと鳴いています。"
end
def sleep
puts "カエル #{@name} は眠りません。一晩中ゲロゲロ鳴いています。"
end
end
class Algae
def initialize(name)
@name = name
end
def grow
p "藻 #{@name} は日光を浴びて育ちます。"
end
end
class WaterLily
def initialize(name)
@name = name
end
def grow
p "睡蓮 #{@name} は浮きながら日光を浴びて育ちます。"
end
end
class Pond
def initialize(number_animals, animal_class,
number_plants, plant_class)
@animal_class = animal_class
@plant_class = plant_class
@animals = []
number_animals.times do |i|
animal = new_organism(:animal, "動物#{i}")
@animals << animal
end
@plants = []
number_plants.times do |i|
plant = new_organism(:plant, "植物#{i}")
@plants << plant
end
end
def simulate_one_day
@plants.each {|plant| plant.grow}
@animals.each {|animal| animal.speak}
@animals.each {|animal| animal.eat}
@animals.each {|animal| animal.sleep}
end
def new_organism(type, name)
if type == :animal
@animal_class.new(name)
elsif type == :plant
@plant_class.new(name)
else
raise "Unknown"
end
end
end
pond = Pond.new(3, Duck, 2, WaterLily)
pond.simulate_one_day
animals と plants の組み合わせを呼び出し元から決めることができます。
この組み合わせも構造化するのは次の part2 で実施してみます。