Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Rubyで泣く子も泣きやむObserverパターン

概要

GoFデザインパターンのObserverパターンについて。
観察者が被験者の変化に応じた処理を行う場合に使用。
観察者と被験者の依存が弱まり、追加が容易になることが利点。

登場人物

Subject = 被験者
ConcreteSubject = 具象被験者
Observer = 観察者
ConcreteObserver = 具象観察者

UML


実装サンプル

サンプル概要

両親が赤ちゃんを観察すると想定します。
赤ちゃんが泣くのを母親が観察した場合、テキパキと対応します。
赤ちゃんが泣くのを父親が観察した場合、あたふたと対応します。

登場人物

Child = 子供:被験者
Baby = 赤ちゃん:具象被験者
Parent = 両親:観察者
Mother = 母親:具象観察者
Father = 父親:具象観察者

UML


サンプルコード

Child

# encoding: Shift_JIS
require_relative './parent'

=begin rdoc
= Childクラス
=end
class Child
  attr_accessor :parent,:name
  NOT_OVERRRIDE = 'not override error'

  def initialize(name,parent)
    @name=name
    @parent=parent
  end
  
  def notify_parent()
    parent.take_care(self)
  end
  def cry()
    raise Child::NOT_OVERRRIDE
  end
end

Baby

# encoding: Shift_JIS
require_relative './child'

=begin rdoc
= Babyクラス
=end
class Baby < Child

  def cry()
    puts 'オギャー、オギャー!'
    notify_parent
  end
end

Parent

# encoding: Shift_JIS
require_relative './child'

=begin rdoc
= Parentクラス
=end
class Parent
  NOT_OVERRRIDE = 'not override error'

  def take_care(child)
    raise Parent::NOT_OVERRRIDE
  end
end

Mother

# encoding: Shift_JIS
require_relative './parent'

=begin rdoc
= Motherクラス
=end
class Mother < Parent
  def take_care(child)
    puts "母は#{child.name}を泣きやませました"
  end
end

Father

# encoding: Shift_JIS
require_relative './parent'

=begin rdoc
= Fatherクラス
=end
class Father < Parent
  def take_care(child)
    puts "父は#{child.name}を泣きやませることができません。。。"
  end
end

main

# encoding: Shift_JIS
require_relative './baby'
require_relative './parent'
require_relative './mother'
require_relative './father'

baby = Baby.new("太郎",Father.new)
baby.cry

baby.parent = Mother.new
baby.cry
出力結果
オギャー、オギャー!
父は太郎を泣きやませることができません。。。
オギャー、オギャー!
母は太郎を泣きやませました