观察者模式(lua版本)

it2022-05-09  33

这是Observer Design Pattern 的一个实现,它利用了闭包。

 

-- Observer design pattern. -- Produces a few functions that have a closure that implements -- subject-observer notification. -- 观察者设计模式。-- 生成一些具有实现闭包的函数--主题观察员通知。 -- Example usage: -- subject.reg, subject.dereg, subject.notify = observer.create() -- subject:reg( "signal", observer, method ) -- subject:reg( "signal", nil, function ) -- subject:notify( "signal" ) -- subject:dereg( "signal", observer, method ) -- subject:dereg( "signal", nil, function )

 -- 用法示例:

  -- subject.reg,subject.dereg,subject.notify = observer.create()  -- 主题:reg(“信号”,观察者,方法)  -- 主题:reg(“信号”,零,功能)  -- 主题:通知(“信号”)  -- 主题:dereg(“信号”,观察者,方法)  --  subject:dereg(“signal”,nil,function)

local table = require("table"); local base = require("base"); local setmetatable = base.setmetatable local ipairs = base.ipairs module("observer") function create() -- Containter holds the filter, and handlers and observers. local container = {} -- Provision for garbage collection, weak metatable and sentinel. local weak = { __mode = "kv" } -- Register -- Creates an observation between the Subject data and the -- Observer data, using filter Signal and handler Method. -- Usage: -- s:register( "update", o, o.m )

   -- 注册   -- 在主题数据和主题数据之间创建观察   -- 观察者数据,使用过滤器信号和处理程序方法。   -- 用法:   --  s:register(“update”,o,o.m)

local register = function( subject, signal, observer, method ) t = container[signal] or {} local o = observer or weak local k = { method, o } setmetatable( k, weak ) table.insert( t, k ) container[signal] = t end -- Deregister -- Removes any observations in the Signal filter, either matching -- the Observer and Method, or the whole filter if both are nil. -- Usage: -- s:deregister( "update" ) -- s:deregister( "update", o ) -- s:deregister( "update", o, o.m )

   -- 取消注册   -- 删除信号过滤器中的任何观察结果,或者匹配   -- 观察者和方法,或整个过滤器,如果两者都是零。   -- 用法:   --  s:注销(“更新”)   --  s:deregister(“update”,o)   --  s:deregister(“update”,o,o.m)

local deregister = function( subject, signal, observer, method ) t = container[signal] if not t then return end if not method and not observer then container[signal] = nil return end local i, v i = #t while i > 0 do v = t[i] or {} if ( not method or v[1] == method ) and ( not observer or v[2] == observer ) then table.remove( t, i ) end i = i - 1 end end -- Notify -- Uses the Signal Filter to notify all observations via their -- registered handlers. -- Usage: -- s:notify( "update" )

   -- 通知   -- 使用信号过滤器通过它们通知所有观察结果   -- 注册处理程序。   -- 用法:   --  s:通知(“更新”)

local notify = function( subject, signal, ... ) t = container[signal] if not t then return end for i, v in ipairs( t ) do if v[2] == weak then v[1](subject, ...) elseif v[2] then v[1](v[2], subject, ...) end -- garbage collected observers (nil) are skipped. end end return register, deregister, notify end -- Signal -- Convienience function that gives a shorthand to sending a -- notification. -- Usage: -- s.update = signal( s, s.notify, "update" ) -- s.update()

 -- 信号 -- 便捷功能,提供发送的速记 -- 通知。 -- 用法: --  s.update = signal(s,s.notify,“update”) --  s.update()

function signal( subject, notify, name ) return function( ... ) return notify( subject, name, ... ) end end

这是一个示例用法。请注意,observer.signal函数有助于创建一种语法,有点模仿C ++框架Qt的信号和插槽模型

require("observer") -- Observers. function a( subject ) print( "a", type(subject) ) end function b( data, subject, extra ) print( "b", data, type(subject), extra ) end o = {} function o:m( subject, extra ) print( "o:m", type(self), type(subject), extra ) end -- First Observation reg, dereg, notify = observer.create() reg( nil, "signal", nil, a ) reg( nil, "signal", "lol", b ) print( "First notification" ) notify( nil, "signal", "zomg" ) dereg( nil, "signal", nil, a ) print( "Second notification" ) notify( nil, "signal" ) -- Second Observation s = {} s.reg, s.dereg, s.notify = observer.create() s.signal = observer.signal( s, s.notify, "signal" ) s:reg( "signal", nil, a ) s:reg( "signal", o, o.m ) print( "Third notification" ) s.signal("rofl") s:dereg( "signal" ) s:reg( "signal", o, o.m ) print( "Fourth notification" ) o = nil collectgarbage() s:notify( "signal" )

 

 

转载于:https://www.cnblogs.com/zhangthree/p/11038693.html

相关资源:数据结构—成绩单生成器

最新回复(0)