基本介绍:
1、当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新,在观察者模式中,主体是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知
2、该模式必须包含两个角色:观察者和被观察对象
3、业务数据是被观察对象,用户界面是观察者
4、观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应
使用场景:
1、当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2、当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象需要被改变。
3、当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,不希望这些对象是紧密耦合的。
4:具体到开发:消息接收
对象列举:
1、抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
2、具体主题(Concrete Subject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
3、抽象观察者(Observer):
为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
4、具体观察者(Concrete Observer):
实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
实现方式:注册—通知—撤销注册
1、观察者:(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。
2、被观察:被观察对象发生了某种变化,从容器中得到所有注册过的观察者,将变化通知观察者。
3、撤销观察:观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。
-- lua
---
--事件派发器,作用如同CCNotificationCenter
local NotificationManager = class("NotificationManager")
NotificationManager._instance = nil
local CALL_TYPE_FUNCTION = 1
local CALL_TYPE_FUNCTION_1 = 2
function NotificationManager:ctor()
self.observerMap = {}
end
-----------------------
--添加监听
--回调函数形式
-- 注册观察者funtable及回调方法funtalbe.test和监听事件MSG_XXX
-- NotificationManager.addObserver(funtable, funtable.test, MSG_XXX)
-- 被观察者中,派发相应事件MSG_XXX
-- NotificationManager.postNotification(MSG_XXX, "param")
-- 移除
-- removeAllObservers(target)
-- removeObserver(target, name)
--@param self NotificationManager self
--@param target table 观察者
--@param selector function 回调函数
--@param name string 事件名称
--@param isSwallow 是否阻挡后续事件传递
function NotificationManager:addObserver(target, selector, name, isSwallow)
assert( target," !! target is nil !! " )
assert( selector," !! selector is nil !! " )
assert( name," !! name is nil !! " )
assert( type(selector) == "function"," !! selector must be function !! " )
if (self:_observerExisted(target, name)) then
return
end
isSwallow = isSwallow or false
local observer = EventObserver:create(target, selector, name, isSwallow)
local observers = self.observerMap[name]
if observers then
table.insert(observers, #observers + 1, observer)
else
self.observerMap[name] = {observer}
end
end
function NotificationManager:removeObserver(target, name)
local observers = self.observerMap[name]
if observers then
for i = 1, #observers do
local observer = observers[i]
if (observer ~= nil) then
if (observer:getName() == name and observer:getTarget() == target) then
observer:clear()
table.remove(observers, i)
return
end
end
end
end
end
function NotificationManager:removeAllObservers(target)
if not target then
return
end
for k, observers in pairs(self.observerMap) do
local removFlag = false
if observers then
for i = #observers, 1, -1 do
local selObserver = observers[i]
if (selObserver:getTarget() == target) then
selObserver:clear()
table.remove(observers, i)
end
end
end
if observers == nil or #observers == 0 then
self.observerMap[k] = nil
end
end
end
---
--派发事件
--@param self NotificationManager self
--@param name string 事件ID
--@param object anytype 回调时传入的参数
function NotificationManager:postNotification(name, object)
local observers = self.observerMap[name]
if observers then
local postServers = {}
--发送时创建新table,方式推送过程中删除引起索引变化
for i = 1, #observers do
postServers[i]=observers[i]
end
for i = 1, #postServers do
local observer = postServers[i]
if observer ~= nil and observer._selector~=nil then
if observer._callType == CALL_TYPE_FUNCTION then
observer._selector(observer._target, object)
elseif observer._callType == CALL_TYPE_FUNCTION_1 then
observer._selector(object)
end
if observer._isSwallow == true then
return
end
end
end
end
end
function NotificationManager:_observerExisted(target, name)
local observers = self.observerMap[name]
if observers then
for i = 1, #observers do
local observer = observers[i]
if (observer and observer:getName() == name and observer:getTarget() == target) then
return true
end
end
end
return false
end
function NotificationManager:getInstance()
if (NotificationManager._instance == nil) then
NotificationManager._instance = NotificationManager.new()
end
return NotificationManager._instance
end
local EventObserver = class("EventObserver")
EventObserver._target = nil
EventObserver._selector = nil
EventObserver._name = nil
EventObserver._callType = nil
EventObserver._isSwallow = nil
function EventObserver:create(target, selector, name, isSwallow)
return EventObserver.new(target, selector, name, isSwallow)
end
function EventObserver:ctor(target, selector, name, isSwallow)
self._callType = CALL_TYPE_FUNCTION
self._isSwallow = isSwallow
if (target ~= nil and (type(selector) == "string")) then
self._selector = target[selector]
elseif (target ~= nil and (type(selector) == "function")) then
self._selector = selector
else
self._callType = CALL_TYPE_FUNCTION_1
end
self._target = target
self._name = name
end
function EventObserver:clear()
self._target = nil
self._selector = nil
self._name = nil
self._isSwallow = nil
end
function EventObserver:performSelector(obj)
if self._callType == CALL_TYPE_FUNCTION then
self._selector(self._target, obj)
elseif self._callType == CALL_TYPE_FUNCTION_1 then
self._selector(obj)
end
end
function EventObserver:getName()
return self._name
end
function EventObserver:getIsSwallow()
return self._isSwallow
end
function EventObserver:getTarget()
return self._target
end
function EventObserver:getSelector()
return self._selector
end
return NotificationManager
文章评论