订阅与发布模式

维基百科:

在许多发布/订阅系统中,发布者发布消息到一个中间的消息代理,然后订阅者向该消息代理注册订阅,由消息代理来进行过滤。消息代理通常执行存储转发的功能将消息从发布者发送到订阅者。

与观察者模式的区别:

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()


小明先生/小姐,您有来自顺丰快递需要接收,,请及时去蜂巢接收
小红先生/小姐,您有来自申通快递需要接收,,请及时去蜂巢接收
小明先生/小姐,您有来自京东快递需要接收,,请及时去蜂巢接收
小明先生/小姐,您有来自韵达快递需要接收,,请及时去蜂巢接收
小红先生/小姐,您有来自中通快递需要接收,,请及时去蜂巢接收

Guess you like

Origin blog.csdn.net/cwcww1314/article/details/120423552