概念:对象之间存在一对多的关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知.
很通俗易懂,就是说n个对象观察1个对象,当这个对象改变的时候,n个对象都被通知,怎么实现呢?就是在1个对象中记录n个对象或者这些对象的某些方法,因为要有接口才能通知到位嘛.
比如:我要实现当a被UpData的时候,通知依赖它的观察者们b跟着执行自己的Updata
Python:
#-*- coding:utf-8 -*-
class A():
def __init__(self):
self.m_Callback = []
def AddCallback(self, func): #添加依赖关系,添加观察者(的执行方法)
self.m_Callback.append(func)
def UpData(self): #a执行更新
print 'a is DoUpData'
for func in self.m_Callback: #通知观察者们,此处执行记录的func方法
func()
class B():
def __init__(self, parent, name):
self.m_Name = name #记录名字用于区分
parent.AddCallback(self.Update) #添加依赖关系
def Update(self): #被通知的更新函数
print self.m_Name, ' is update'
def Do():
a = A() #a是被观察者
b = [] #b 是观察者们
nameList = ['1号', '2号', '3号']
for name in nameList:
obj = B(a, name)
b.append(obj)
a.UpData() #a执行修改,这时请观察被观察者们是否得到通知,此处为执行UpData
Do()
输出结果:
a is DoUpData
1号 is update
2号 is update
3号 is update
解释:这里只执行了a.UpData,然而在a.UpData方法中执行观察者们各自添加的func方法,即通知观察者们的操作.
观察者模式主要是建立一套触发机制,让被观察者能够触发”通知观察者”的操作们,很像模板.
有优点肯定也有缺点:
1:通知一般是遍历所有被记录观察者们或其方法,所以时间花费可想而知.
2:可能会有循环通知,比如a通知b,b通知c,c再通知a,造成死循环,重点注意.
3:引用问题,在python中这种设置回调的方式导致b.func在别处被引用,所以导致b无法正常释放,而其他语言中可能造成野指针,如b被释放掉了,这是再来执行b.func.
实际应用举例:
游戏中角色升级会改变攻击防御等面板信息,所以让这些信息的对象与角色等级建立观察关系,这样在角色升级的时候,顺便调用刷新这些面板信息的方法,就可以很方便地处理很多困扰了.