替代观察者模式 |
|
module(..., package.seeall) -- Register local function register( self, observer, method ) local t = {} t.o = observer t.m = method table.insert( self, t ) end -- Deregister local function deregister( self, observer, method ) local i local n = #self for i = n, 1, -1 do if (not observer or self[i].o == observer) and (not method or self[i].m == method) then table.remove( self, i ) end end end -- Notify local function notify( self, ... ) local i local n = #self for i = 1, n do self[i].m( self[i].o, ... ) end end -- signal metatable local mt = { __call = function( self, ... ) self:notify(...) end } function signal() local t = {} t.register = register t.deregister = deregister t.notify = notify setmetatable( t, mt ) return t end
由于信号现在是显式对象,而不是隐式数据(例如字符串),因此我们使用表格语法糖来处理它们。为了方便起见,包含了 __call 元方法,因此我们可以直接使用信号。
observer = require( "alt_obs" ) alice = {} function alice:slot( param ) print( self, param ) end bob = {} bob.alert = observer.signal() bob.alert:register( alice, alice.slot ) bob.alert( "Hi there" ) bob.alert:deregister( alice ) bob.alert( "Hello?" )
-- WilliamBubel