observable.rb
30分プログラム、その35。
Observableモジュールを試してみよう。
$ ruby observable.rb 44 DigitObserver:44 GraphObserver:******************************************** 27 DigitObserver:27 GraphObserver:*************************** 27 DigitObserver:27 GraphObserver:*************************** ..............
require 'observer' # ブロックで登録するメソッドを追加 module Observable alias_method :_notify_observers_,:notify_observers alias_method :_count_observers_,:count_observers def add_observer_proc(&block) @observer_proc = [] unless @observer_proc @observer_proc << block end def count_observers _count_observers_() + @observer_proc.size end def notify_observers(*args) if changed? then @observer_proc.each{|proc| proc.call *args } end _notify_observers_ *args end end class RandomGenerator include Observable attr_reader :number def execute 20.times{ @number = rand 50 changed notify_observers self } end end class DigitObserver def update(gen) puts "DigitObserver:#{gen.number}" end end class GraphObserver def update(gen) puts "GraphObserver:#{'*' * gen.number}" end end rg = RandomGenerator.new rg.add_observer DigitObserver.new rg.add_observer GraphObserver.new rg.add_observer_proc{|gen| puts gen.number } rg.execute
- デザパタの例は増補改訂版Java言語で学ぶデザインパターン入門より
- WOLはまた今度
- Rubyならクラス単位の登録じゃなくて、ブロックの登録であるべきだろ。というわけで、ちょっと改造した
# 部屋が暑くて死にそう