利用lua元表實現觀察者模式組件

你們都知道,觀察者(Observer)模式的定義,是指多個對象間存在一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新。這種模式有時又稱做發佈-訂閱模式、模型-視圖模式,它是對象行爲型模式。其實質就是被觀察者保存着全部觀察者的索引,當本身數據更新時,便於通知全部觀察者。所以,這個被觀察者必定要實現如下方法:
addObserver()——添加觀察者
removeObserver()——移除觀察者
notify()——通知觀察者數據變動,在這個方法中,須要遍歷觀察者索引,執行response()方法
response()——觀察者實現的接受數據改變的方法
image.png
在上一節中,咱們講了lua底下的組件機制,對象經過擴展BehaviorExtend,使之可以bind_behavior()綁定組件,今天,咱們實現一個觀察者組件,實現的目的:當對象綁定了該觀察者組件,可以成爲一個被觀察者。
在lua狀況下,讀寫數據,咱們要經過table的元表來實現(具體依靠__index和__newindex),所以,咱們額外實現一個方法initDataProxy(),用於初始化數據的讀寫操做。咱們主要分析該方法的實現,加深理解lua元表的功能:lua

function ObserverBehavior:initDataProxy(object) 
    local oldMt = getmetatable(object)
    local newMt = clone(oldMt)
    newMt.__index = function(t,k)
        local v = self.m_propertyMap[k]
        if v ~= nil then
            if v == nilValue then
                return nil
            else
                return v
            end
        end
        if oldMt and oldMt.__index then
            if type(oldMt.__index) == "function" then
                return oldMt.__index(t, k)
            else
                return oldMt.__index[k]
            end
        end
    end
    newMt.__newindex = function(t,k,v)
        local oldVal = self.m_propertyMap[k]
        if self.m_lockWrite == true and oldVal == nil then
            error("lock 之後不容許寫入新數據"..tostring(k))
            return
        end
        self.m_propertyMap[k] = v == nil and nilValue or v
        self:__notifyDataChanged(object, k, v, oldVal)
    end
    object.dtor = object.dtor -- 修改了_index元表,須要將dtor的引用掛在object上,不然執行不進原有的dtor
    setmetatable(object, newMt)
    self.m_objectMeta = oldMt
end

__index元表用於table的讀操做,所以,咱們重寫了object的__index元表,__newindex元表用於table的寫操做,咱們重寫__newindex元表後,每次寫入後都會進行數據通知,由__notifyDataChanged方法提供。同時還增長了鎖定數據功能,防止self.m_propertyMap中的數據被隨意更改。spa

相關文章
相關標籤/搜索