`
orcl_zhang
  • 浏览: 242327 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

ruby cookbook -- 使用回掉的松偶合系统

    博客分类:
  • ruby
阅读更多
7.11 使用回掉的松偶合系统
Coupling Systems Loosely with Callbacks
Here's a mixin module that gives each instance of a class its own hash of "listener" callback blocks. An outside object can listen for a particular event by calling subscribe with the name of the event and a code block. The dispatcher itself is responsible for calling notify with an appropriate event name at the appropriate time, and the outside object is responsible for passing in the name of the event it wants to "listen" for.
	module EventDispatcher
	  def setup_ 
listeners
	    @event_dispatcher_listeners = {}
	  end

	  def subscribe(event, &callback)
	    (@event_dispatcher_listeners[event] ||= []) << callback
	  end

	  protected
	  def notify(event, *args)
	    if @event_dispatcher_listeners[event]
	      @event_dispatcher_listeners[event].each do |m|
	        m.call(*args) if m.respond_to? :call
	      end
	    end
	    return nil
	  end
	end

Here's a Factory class that keeps a set of listeners. An outside object can choose to be notified every time a Factory object is created, or every time a Factory object produces a widget:
 class Factory
	  include EventDispatcher

	def initialize
	  setup_listeners
	end

	def produce_widget(color)
	  #Widget creation code goes here…
	    notify(:new_widget, color)
	  end
	end


Here's a listener class that's interested in what happens with Factory objects:
	class WidgetCounter
	  def initialize(factory)
	    @counts = Hash.new(0)
	    factory.subscribe(:new_widget) do |color|
	      @counts[color] += 1
	      puts "#{@counts[color]} #{color} widget(s) created since I started watching."
	    end
	  end
	end

Finally, here's the listener in action:
    f1 = Factory.new  
    WidgetCounter.new(f1)  
    f1.produce_widget("red")  
    # 1 red widget(s) created since I started watching.  
      
    f1.produce_widget("green")  
    # 1 green widget(s) created since I started watching.  
      
    f1.produce_widget("red")  
   # 2 red widget(s) created since I started watching.  
     
   # This won't produce any output, since our listener is listening to  
   # another Factory.  
   Factory.new.produce_widget("blue")  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics