「Rubyによるデザインパターン」の読書メモです。
時々、個人の見解入りです。
用語
Subject: サブジェクト
ニュースを持っているクラス
Observer: オブザーバ
ニュースを得ることに関心のあるオブジェクト
変更前
class Payroll
def update(changed_employee)
puts("#{changed_employee.name}のために小切手を切ります!")
puts("彼の給料はいま#{changed_employee.salary}です!")
end
end
class Employee
attr_reader :name, :title, :salary
def initialize(name, title, salary, payroll)
@name = name
@title = title
@salary = salary
@payroll = payroll
end
def salary=(new_salary)
@salary = new_salary
@payroll.update(self)
end
end
payroll = Payroll.new
fred = Employee.new('Fred', 'Crane Operator', 3000, payroll)
fred.salary = 3500
継承を利用したパターン
class Subject
def initialize
@observers = []
end
def add_observer(observer)
@observers << observer
end
def delete_observer(observer)
@observers.delete(observer)
end
def notify_observers
@observers.each do |observer|
observer.update(self)
end
end
end
class Payroll
def update(changed_employee)
puts("#{changed_employee.name}のために小切手を切ります!")
puts("彼の給料はいま#{changed_employee.salary}です!")
end
end
class Employee < Subject
attr_reader :name, :title, :salary
def initialize(name, title, salary)
super()
@name = name
@title = title
@salary = salary
end
def salary=(new_salary)
@salary = new_salary
notify_observers
end
end
fred = Employee.new('Fred', 'Crane Operator', 3000)
payroll = Payroll.new
fred.add_observer(payroll)
fred.salary = 3500
モジュールを利用したパターン
module Subject
def initialize
@observers = []
end
def add_observer(observer)
@observers << observer
end
def delete_observer(observer)
@observers.delete(observer)
end
def notify_observers
@observers.each do |observer|
observer.update(self)
end
end
end
class Payroll
def update(changed_employee)
puts("#{changed_employee.name}のために小切手を切ります!")
puts("彼の給料はいま#{changed_employee.salary}です!")
end
end
class Employee
include Subject
attr_reader :name, :title, :salary
def initialize(name, title, salary)
super()
@name = name
@title = title
@salary = salary
end
def salary=(new_salary)
@salary = new_salary
notify_observers
end
end
fred = Employee.new('Fred', 'Crane Operator', 3000)
payroll = Payroll.new
fred.add_observer(payroll)
fred.salary = 3500
ライブラリを利用したパターン
require 'observer'
class Payroll
def update(changed_employee)
puts("#{changed_employee.name}のために小切手を切ります!")
puts("彼の給料はいま#{changed_employee.salary}です!")
end
end
class Employee
include Observable
attr_reader :name, :title, :salary
def initialize(name, title, salary)
@name = name
@title = title
@salary = salary
end
def salary=(new_salary)
@salary = new_salary
changed
notify_observers(self)
end
end
fred = Employee.new('Fred', 'Crane Operator', 3000)
payroll = Payroll.new
fred.add_observer(payroll)
fred.salary = 3500