第5章 変更に追従する: Observer part2
Ruby
Published: 2019-06-24

「Rubyによるデザインパターン」の読書メモです。

時々、個人の見解入りです。

注意点

Observerパターンを使うときに発生する問題の多くは、更新の頻度とタイミングについてです。

実際に何か変更されたのでなければ、おそらくオブザーバに通知すべきではありません。

変更された時のみ通知を送るようにするパターン

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)
    if @salary == new_salary
      nil
    end

    @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 = 3000
fred.salary = 3100

変更をまとめて通知するパターン

require 'observer'

class Payroll
  def update(changed_employee)
    puts("#{changed_employee.name}のために小切手を切ります!")
    puts("title: #{changed_employee.title}")
    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)
    if @salary == new_salary
      nil
    end

    @salary = new_salary
  end

  def title=(new_title)
    if @title == new_title
      nil
    end
    @title = new_title
  end

  def changes_complete
    changed
    notify_observers(self)
  end
end

fred = Employee.new('Fred', 'Crane Operator', 3000)
payroll = Payroll.new
fred.add_observer(payroll)

fred.title = 'superman'
fred.salary = 9000
fred.changes_complete