Singleton
概要
そのクラスのインスタンスが一つしかないことを保証する
オブジェクトを外部から直接生成させることを防ぎ、クラス自体に同時に生成できるオブジェクトの数を管理させる
使い道
常に同じオブジェクトをプログラム内で扱いたい
DBのコネクション数を制限したい
例
require 'singleton'
class SingletonObject
# instanceメソッドが定義され、newメソッドがprivateに設定される
include Singleton
attr_accessor :counter, :name
def initialize
@counter = 0
@name = "Singleton"
end
end
obj1 = SingletonObject.instance
obj1.counter += 1
p "--- #{obj1.name} ---"
p obj1.counter
obj2 = SingletonObject.instance
obj2.counter += 1
obj2.name = "UpdatedName"
p "--- #{obj1.name} ---"
p obj2.counter
p obj1.equal?(obj2)
# "--- Singleton ---"
# 1
# "--- UpdatedName ---"
# 2
# true
Builder
概要
複雑なインスタンスの生成を他のオブジェクト(Director)にまかせる
Builderが作業を担当
Directorが作業過程を担当
例
# ConcreteBuilder
class SaltWater
attr_accessor :water, :salt, :color
def initialize(water, salt, color)
@water = water
@salt = salt
@color = color
end
def add_material(salt_amount)
@salt += salt_amount
end
def update_color
@color = "blue"
end
end
# ConcreteBuilder
class SugarWater
attr_accessor :water, :sugar, :color
def initialize(water, sugar, color)
@water = water
@sugar = sugar
@color = color
end
def add_material(sugar_amount)
@sugar += sugar_amount
end
def update_color
@color = "red"
end
end
# Builder
class WaterWithMaterialBuilder
attr_reader :water_with_material
def initialize(class_name)
@water_with_material = class_name.new(0,0, "white")
end
def add_material(material_amount)
@water_with_material.add_material(material_amount)
end
def add_water(water_amount)
@water_with_material.water += water_amount
end
def update_color
@water_with_material.update_color
end
def result
@water_with_material
end
end
# Director
class Director
attr_reader :builder
def initialize(builder)
@builder = builder
end
def magic
@builder.add_water(150)
@builder.add_material(90)
@builder.add_material(35)
@builder.update_color()
end
end
builder = WaterWithMaterialBuilder.new(SugarWater)
director = Director.new(builder)
director.magic
p builder.result
p director.builder.water_with_material.color
# #<SugarWater:0x007fed55824b10 @water=150, @sugar=125, @color="red">
# "red"
builder = WaterWithMaterialBuilder.new(SaltWater)
director = Director.new(builder)
director.magic
p builder.result
p director.builder.water_with_material.color
# #<SaltWater:0x007fed5582fe98 @water=150, @salt=125, @color="blue">
# "blue"
Abstract Factory
概要
関連し合うオブジェクトの集まりを生成することができる
矛盾のないオブジェクトの生成を行うため
例
class DinnaerFactory
def initialize
end
def createDinner
return [createAppetizer,createMain]
end
def createMain
end
def createAppetizer
end
end
class Soup
def initialize
end
end
class Rice
def initialize
end
end
class Salad
def initialize
end
end
class Pizza
def initialize
end
end
class JapaneseFactory < DinnaerFactory
def createMain
Rice.new
end
def createAppetizer
Soup.new
end
end
class ItalyFactory < DinnaerFactory
def createMain
Pizza.new
end
def createAppetizer
Salad.new
end
end
japanese = JapaneseFactory.new
puts japanese.createDinner
italy = ItalyFactory.new
puts italy.createDinner
Factory Method
概要
インスタンスの生成をサブクラスに任せる
インスタンスの生成部分を切り離すことで、結合度を下げて追加・変更・保守を容易に
例
class Saxophone
def initialize(name)
@name = name
end
def play
puts "#{self.class} #{@name} is being played!"
end
end
class Trumpet
def initialize(name)
@name = name
end
def play
puts "#{self.class} #{@name} is being played!"
end
end
class InstrumentFactory
def initialize(number_instruments)
@instruments = []
number_instruments.times do |i|
instrument = new_instrument("No.#{i + 1}")
@instruments << instrument
end
end
def ship_out
@tmp = @instruments.dup
@instruments = []
@tmp
end
end
class SaxophoneFactory < InstrumentFactory
def new_instrument(name)
Saxophone.new(name)
end
end
class TrumpetFactory < InstrumentFactory
def new_instrument(name)
Trumpet.new(name)
end
end
factory = SaxophoneFactory.new(3)
saxophones = factory.ship_out
saxophones.each { |saxophone| saxophone.play }
factory = TrumpetFactory.new(2)
trumpets = factory.ship_out
trumpets.each { |trumpet| trumpet.play }