読者です 読者をやめる 読者になる 読者になる

Yamakichi’s blog

yamakichiの技術ブログ

Observerパターン Ruby

思考の整理 開発 Ruby

Observerパターン

オブザーバーパターンとは

Observerとは「観測者」 あるオブジェクトの状態が変化した際に、そのオブジェクト自信が「観測者」に「通知」をする仕組み。 オブザーバーは3つのオブジェクトで構成される。

  • サブジェクト(subject):変化する側のオブジェクト
  • オブザーバ(Observer):変化を関連するオブジェクトに通知するインターフェース
  • 具象オブザーバ(ConcreateObserver):状態の変化に関連して具体的な処理を行う

状態とは、クラスが持つ変数の値のこと。

用いるメリット

  • オブジェクト間の依存度を下げることができる
  • 通知先の管理をオブザーバーが行うことで、サブジェクトは通知側を意識しなくていい

実装

  • Employee(サブジェクト):従業員を表す
  • Observable(オブザーバ):従業員のニュースを監視する仕組み(observer/Observable)
  • Payroll(具体オブザーバ1):給与の小切手の発行を行う
  • TaxMan(具体オブザーバ2):税金の請求書の発行を行う
require 'observer'
class Employee
  include Observable # Observerとして働く

  attr_reader :name, :title, :salary

  def initialize(name, title, salary)
    @name = name
    @title = title
    @salary = salary
    # 監視するインスタンスを追加
    add_observer(Payroll.new)
    add_observer(TaxMan.new)
  end

  # 給与をセットして、ConcreteObserverに通知する
  def salary=(new_salary)
    @salary = new_salary
    # changedで変化があったかを確認する
    changed
    # 変化があった場合に以下実行される
    notify_observers(self)
  end
end

#----------------具体オブザーバ---------------

# 給与の小切手の発行を行う
class Payroll
  # 変更通知用にupdateメソッドを持っている
  def update(changed_employee)
    puts "彼の給料は#{changed_employee.salary}になりました!#{changed_employee.title}のために新しい小切手を切ります。"
  end
end

# 税金の請求書の発行を行う
class TaxMan
  # 変更通知用にupdateメソッドを持っている
  def update(changed_employee)
    puts "#{changed_employee.name}に新しい税金の請求書を送ります"
  end
end

john = Employee.new('John', 'Senior Vice President', 5000)
john.salary = 6000
#=> 彼の給料は6000になりました!Senior Vice Presidentのために新しい小切手を切ります。
#=> Johnに新しい税金の請求書を送ります
john.salary = 7000
#=> 彼の給料は7000になりました!Senior Vice Presidentのために新しい小切手を切ります。
#=> Johnに新しい税金の請求書を送ります

ストラテジーとの違い

  • オブザーバー:発生しているオブジェクトに対してイベントを通知している
  • ストラテジー:何らかの処理を行うためにオブジェクトを取得している