维基百科:
在许多发布/订阅系统中,发布者发布消息到一个中间的消息代理,然后订阅者向该消息代理注册订阅,由消息代理来进行过滤。消息代理通常执行存储转发的功能将消息从发布者发送到订阅者。
与观察者模式的区别:
1.发布者与订阅者无法相互感知,双方无法知道对方是谁.
2,非实时传递信息,信息可以储存到一定时间再传递到订阅者.
3,发布订阅模式常用于不同的交互模块.比如消息队列.
4,接收者可能会接收到不同类别的消息.可以自定义接收信息.而观察者模式一旦有状态变化,则所有的观察者都要接收.观察不是一种主动的观察而是一种被动地接收通知
初级代码理解形式,可能有误,后续修改.
以蜂巢为例
# encoding: utf-8
class PostMan(object):
def __init__(self, name, hive_box):
self.name = name
self.hive_box = hive_box
def publish(self, msg):
self.hive_box.notify(msg)
class Subscriber(object):
def __init__(self, name, hive_box):
self.name = name
self.hive_box = hive_box
def subscribe(self, msg):
self.hive_box.add_sub(self, msg)
def unsubscribe(self, msg):
self.hive_box.del_sub(self, msg)
def run(self, msg):
print("%s先生,您有快递需要接收,来自%s,请及时接收" % (self.name, msg))
class HiveBox(object):
def __init__(self, name):
self.name = name
# 每个消息类型维护一个对列
self.msg_queue = {}
self.subscribers = []
# 消息队列添加了新的消息类型
def notify(self, msg):
self.msg_queue.setdefault(msg, [])
def add_sub(self, subscribe, msg):
try:
self.msg_queue[msg].append(subscribe)
except ValueError:
print('无该快递')
def del_sub(self, subscribe, msg):
try:
self.msg_queue[msg].remove(subscribe)
except ValueError:
print('无该快递')
def send(self, msg):
if msg in self.msg_queue:
for sub in self.msg_queue[msg]:
sub.run(msg)
if __name__ == '__main__':
# 准备送快递,收快递的不在家
hive_box = HiveBox('汤臣一品小区')
postman_one = PostMan('汤哥', hive_box)
postman_one.publish('蜂巢1号')
sub_one = Subscriber('小明', hive_box)
sub_two = Subscriber('小红', hive_box)
sub_one.subscribe('蜂巢1号')
sub_two.subscribe('蜂巢1号')
hive_box.send('蜂巢1号')
#result
小明先生,您有快递需要接收,来自蜂巢1号,请及时接收
小红先生,您有快递需要接收,来自蜂巢1号,请及时接收
优化版本,易于理解:
# encoding: utf-8
class PostMan(object):
def __init__(self, name, hive_box):
self.name = name
self.hive_box = hive_box
# 中通,顺丰,申通
def publish(self, msg):
self.hive_box.notify(msg)
class Subscriber(object):
def __init__(self, name, hive_box):
self.name = name
self.hive_box = hive_box
def subscribe(self, msg):
self.hive_box.add_sub(self, msg)
def unsubscribe(self, msg):
self.hive_box.del_sub(self, msg)
def run(self, msg):
print("%s先生/小姐,您有来自%s快递需要接收,,请及时去蜂巢接收" % (self.name, msg))
class HiveBox(object):
def __init__(self, name):
self.name = name
# 每个消息类型维护一个对列
self.msg_queue = []
self.subscribers = {}
# 消息队列添加了新的消息类型
def notify(self, msg):
self.msg_queue.append(msg)
def add_sub(self, subscribe, msg):
self.subscribers.setdefault(msg, []).append(subscribe)
def del_sub(self, subscribe, msg):
self.subscribers[msg].remove(subscribe)
def updates(self):
for msg in self.msg_queue:
for subs in self.subscribers[msg]:
subs.run(msg)
self.msg_queue = []
if __name__ == '__main__':
# 准备送快递,收快递的不在家
hive_box = HiveBox('蜂巢1号')
postman_one = PostMan('顺丰小哥', hive_box)
postman_one.publish('顺丰')
postman_one = PostMan('申通小哥', hive_box)
postman_one.publish('申通')
postman_one = PostMan('京东小哥', hive_box)
postman_one.publish('京东')
postman_one = PostMan('韵达小哥', hive_box)
postman_one.publish('韵达')
postman_one = PostMan('中通小哥', hive_box)
postman_one.publish('中通')
sub_one = Subscriber('小明', hive_box)
sub_two = Subscriber('小红', hive_box)
sub_one.subscribe('顺丰')
sub_two.subscribe('申通')
sub_two.subscribe('中通')
sub_one.subscribe('京东')
sub_one.subscribe('韵达')
hive_box.updates()
小明先生/小姐,您有来自顺丰快递需要接收,,请及时去蜂巢接收
小红先生/小姐,您有来自申通快递需要接收,,请及时去蜂巢接收
小明先生/小姐,您有来自京东快递需要接收,,请及时去蜂巢接收
小明先生/小姐,您有来自韵达快递需要接收,,请及时去蜂巢接收
小红先生/小姐,您有来自中通快递需要接收,,请及时去蜂巢接收