大纲 | 小结 |
---|---|
基础准则 | 基础准则 |
创建型模式 | 单例模式 |
- | 原型模式 |
- | 简单工厂模式 |
- | 抽象工厂模式 |
- | 建造者模式 |
结构型模式 | 代理模式 |
- | 适配器模式 |
- | 桥接模式 |
- | 装饰器模式 |
- | 门面/外观模式 |
- | 享元模式 |
- | 组合模式 |
行为型模式 | 模板方法模式 |
- | 策略模式 |
- | 命令模式 |
- | 职责链模式 |
- | 状态模式 |
- | 观察者模式 |
- | 中介者模式 |
- | 迭代器模式 |
- | 访问者模式 |
- | 备忘录模式 |
- | 解释器模式 |
观察者模式, 顾名思义, 有个类实例, 作为观察者身份存在于程序中, 他的职责是, 观察事件和汇报事件给监听者
优点:
- 有效降低代码耦合度
- 添加方便
- 移除也方便
- 方便调试
缺点:
- 事件种类过多, 或监听者过多, 都会导致效率下降
观察者会把事件分发给侦听者, 不限制数量, 观察者也可以接收被观察对象的相同事件, 不限制数量, 因此, 通过事件名和被观察对象可以很好的区分出, 用来给侦听者判断依据
如果未侦听任意事件, 或者侦听的事件未发生, 那么侦听者不会触发报告函数.
观察者其实很好写, 一般需要数组(如果需要优先级) 或字典来存储事件, 事件对应的侦听者列表, 当事件被触发, 那么侦听者列表就会被遍历广播, 提醒所有侦听这个事件的对象, 有事件发生
观察者模型
class NtfName:
game_run = "game_run"
game_end = "game_end"
class NtfCenter(object):
_single = None
@classmethod
def One(cls):
if cls._single is None:
cls._single = NtfCenter()
return cls._single
def __init__(self):
self._dict = {}
# super().__init__()
def add(self, ntfName, target, func):
if ntfName not in self._dict:
self._dict[ntfName] = NtfObserve(ntfName)
# self._dict[ntfName].append()
self._dict[ntfName].add(target, func)
def remove(self, ntfName=None, target=None, func=None):
if ntfName is None and target is None and func is None:
return
if ntfName is not None:
if ntfName in self._dict:
self._dict[ntfName].remove(target, func)
else:
for key in self._dict:
key.remove(target, func)
def post(self, ntfName=None, obj:object=None):
if ntfName in self._dict:
self._dict[ntfName].broadcast(obj)
class NtfObserve(object):
def __init__(self, ntfName:str):
self.name = ntfName
self.observes = []
def add(self, target, func):
self.observes.append({"t":target, "f":func})
def remove(self, target=None, func=None):
if target is None and func is None:
self.observes.clear()
return
for i in range(len(self.observes)-1, -1, -1):
if self.observes[i]['t'] is target:
if func is not None:
if self.observes[i]['f'] == func:
self.observes.pop(i)
break
else:
self.observes.pop(i)
def broadcast(self, obj:object):
self.obj = obj
for key in self.observes:
key['f'](self)
self.obj = None
绑定和广播
class listener1:
def ntf(self,no:NtfObserve):
if no.name is NtfName.game_run:
print('listener1 do game run func %d'%no.obj)
elif no.name is NtfName.game_end:
print('listener1 also do game end func %d'%no.obj)
class listener2:
def ntf(self,no:NtfObserve):
if no.name is NtfName.game_end:
print("listener2 only do game end func %d"%no.obj)
def ntf2(self,no:NtfObserve):
if no.name is NtfName.game_end:
print('listener2 also do game end func listen %d'%no.obj)
if __name__ == "__main__":
l1 = listener1()
l2 = listener2()
NtfCenter.One().add(NtfName.game_run, l1, l1.ntf)
NtfCenter.One().add(NtfName.game_end, l1, l1.ntf)
NtfCenter.One().add(NtfName.game_run, l2, l2.ntf)
NtfCenter.One().add(NtfName.game_end, l2, l2.ntf)
NtfCenter.One().add(NtfName.game_end, l2, l2.ntf2)
# NtfCenter.One().remove(NtfName.game_run)
# NtfCenter.One().remove(NtfName.game_run,l1)
NtfCenter.One().remove(NtfName.game_end,l2, l2.ntf)
NtfCenter.One().post(NtfName.game_run, 1)
NtfCenter.One().post(NtfName.game_end, 2)
非常简单, 你也可以自己写一个
其中包括
- add 绑定
- remove 移除
- clear 清空
- post 广播
- param 传递参数