• 观察者模式(lua版本)


    这是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" )
     
  • 相关阅读:
    在智能手机上跟踪ADS-B系统的飞机航线信息
    用C#将XML转换成JSON
    在DB2中使用EXPORT实现将数据导出文本文件
    使用Powerdesigner生成设计的数据表(一张或多张)的测试数据
    PowerDesigner常用设置
    转载自——Json.Net如何在序列化之前修改属性值
    转载自——Json.net动态序列化以及对时间格式的处理
    Newtonsoft.Json序列化和反序列
    DB2 数据库中字段特定字符替换为空
    常用公共DNS服务器地址
  • 原文地址:https://www.cnblogs.com/zhangthree/p/11038693.html
Copyright © 2020-2023  润新知