크리에이티브 커먼즈 라이선스
Creative Commons License
 
module EventDispatcher
	def setup_listeners
		@listeners = {}
		@change = false
	end

	def register_listener(listener, event)
		(@listeners[event] ||= []) << listener
	end

	def remove_listener(listener, event)
		(@listeners[event] ||= []).delete listener
	end

	def remove_listeners(event)
		@listeners[event] = []
	end

	def count_listeners(event)
		(@listeners[event] ||= []).size
	end

	def changed?
		@change
	end

	protected
	def notify(event, arg)
		return if not @change
		if @listeners[event]
			callback = ("update_at_" + event.to_s).to_sym
			@listeners[event].each do |listener|
				if listener.respond_to? callback
					listener.send callback, arg
				elsif listener.respond_to? :update
					listener.update event, arg
				end
			end
		end
		@change = false
		return nil	
	end

	def changed
		@change = true
	end
end	

class TestFactory
	include EventDispatcher
	
	def initialize
		setup_listeners
	end	

	def create_button(color)
		changed
		notify(:new_button, {:color => color})
	end

	def create_label(text)
		changed
		notify(:new_label, {:text => text})
	end
end

class TestWidgetCounter
	def initialize(widget_factory)
		@counts = Hash.new(0)
		widget_factory.register_listener(self, :new_button)
		widget_factory.register_listener(self, :new_label)
	end

	def update(event, arg)
		case event
		when :new_label
			puts "#{arg[:text]} label created."
		end	
	end

	def update_at_new_button(arg)
		color = arg[:color]
		@counts[color] += 1
		puts "#{@counts[color]} #{color} button(s) created."
	end
end



f = TestFactory.new
t = TestWidgetCounter.new(f)

f.create_button("red")
f.create_button("blue")
f.create_button("green")
f.create_label("name")
f.create_button("red")

f.remove_listener(t, :new_label)
f.create_label("cellphone")

f.create_button("blue")


Output:
1
2
3
4
5
6
1 red button(s) created.
1 blue button(s) created.
1 green button(s) created.
name label created.
2 red button(s) created.
2 blue button(s) created.


APE 0.50a 포팅할 때 사용하려고 만들었던 EventDispatcher
저작자 표시 비영리 동일 조건 변경 허락

'객체지향 프로그래밍 > 디자인 페턴' 카테고리의 다른 글

ruby EventDispatcher  (0) 2011/11/06
Thread Pool  (6) 2009/04/10
Object Pool  (11) 2009/03/08
MVC(Model-View-Controller) 디자인 패턴에 대한 좋은 아티클들  (6) 2008/08/08

댓글을 달아 주세요