设计模式02观察者模式
2017-05-16 本文已影响33人
极光火狐狸
代码
# -.- coding:utf-8 -.-
# __author__ == 'zhengtong'
from __future__ import print_function
def exception_wrapper(func):
def wrapper(self, *args, **kwargs):
try:
result = func(self, *args, **kwargs)
if result is not None:
return result
except Exception:
import sys, traceback
ex_type, ex, tb = sys.exc_info()
traceback.print_exception(ex_type, ex, tb)
return False
return True
return wrapper
class Producer(object):
def __init__(self):
self.topic = {}
@exception_wrapper
def create_topic(self, topic):
if topic not in self.topic:
self.topic[topic] = []
@exception_wrapper
def publish(self, topic, data):
self.create_topic(topic)
if not self.topic[topic]:
return '当前主题没有任何观察者/订阅者/消费者'
self.notify_observers(topic, data)
@exception_wrapper
def subscribe(self, topic, *observers):
self.create_topic(topic)
for observer in observers:
if observer not in self.topic[topic]:
self.topic[topic].append(observer)
@exception_wrapper
def unsubscribe(self, topic, *observers):
l = self.topic[topic]
for observer in observers:
l.pop(l.index(observer))
@exception_wrapper
def notify_observers(self, topic, data):
for observer in self.topic[topic]:
observer.get_message(data)
class SendMailObserver(object):
def get_message(self, data):
print('send mail to: ', data)
class WriteMailObserver(object):
def get_message(self, data):
print('write mail to: ', data)
class ProcessMailObserver(object):
def get_message(self, data):
print('ProcessMail mail: ', data)
if __name__ == '__main__':
# 启动Producer服务
producer = Producer()
# 创建主题
producer.create_topic('sss')
producer.create_topic('bbb')
# 注册观察者/订阅者/消费者
send_mail_observer = SendMailObserver()
write_mail_observer = WriteMailObserver()
Process_mail_observer = ProcessMailObserver()
producer.subscribe('send_mail', *[send_mail_observer,
write_mail_observer,
Process_mail_observer])
# 查看每个队列有多少的consumer
print('producer.topic: ', producer.topic)
# 发布消息
producer.publish('send_mail', '330356463@qq.com')
# 移除观察者/订阅者/消费者
producer.unsubscribe('send_mail', write_mail_observer)
# 查看每个队列有多少的consumer
print(producer.topic)
# 查看现在总共有几个频道
print(producer.topic.keys())
# 显示结果
producer.topic: {'bbb': [], 'sss': [], 'send_mail': [<__main__.SendMailObserver object at 0x03492F50>, <__main__.WriteMailObserver object at 0x03492F70>, <__main__.ProcessMailObserver object at 0x03492F90>]}
send mail to: 330356463@qq.com
write mail to: 330356463@qq.com
ProcessMail mail: 330356463@qq.com
{'bbb': [], 'sss': [], 'send_mail': [<__main__.SendMailObserver object at 0x03492F50>, <__main__.ProcessMailObserver object at 0x03492F90>]}
['bbb', 'sss', 'send_mail']
模式总结
观察者模式强调的是松耦合,通过程序之间的强约定弱依赖实现通用场景的<发布/订阅>模型。
核心理念
当数据发生变化时执行回调函数(provide a callback for notification of events/changes to data).
模式类型
行为模式
设计原则
- 为了交互对象之间的松耦合设计而努力。
参考
- [x] Head First设计模式
- [x] Head First设计模式Python版源码
- [x] patterns-idioms
- [x] py-patterns