你們都知道,觀察者(Observer)模式的定義,是指多個對象間存在一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新。這種模式有時又稱做發佈-訂閱模式、模型-視圖模式,它是對象行爲型模式。其實質就是被觀察者保存着全部觀察者的索引,當本身數據更新時,便於通知全部觀察者。所以,這個被觀察者必定要實現如下方法:
addObserver()——添加觀察者
removeObserver()——移除觀察者
notify()——通知觀察者數據變動,在這個方法中,須要遍歷觀察者索引,執行response()方法
response()——觀察者實現的接受數據改變的方法
在上一節中,咱們講了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