伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

订阅者模式,公众号、B站、快手用了都说好!

来源:本站原创 浏览:138次 时间:2021-08-30


大家好,今天和大家来聊一个新的设计模式——订阅者模式。

这个模式在我们的生活当中非常常见,可以说是几乎所有的媒体平台都用或多或少地用到了这个模式。比如公众号,我们来仔细梳理一下公众号这个平台当中的整个逻辑,会发现其实这里面一共有三方存在,这三方呈一个三角关系。

三方订阅关系

画出来的话大概是这个样子:


这张图大家应该很好理解,TechFlow每天把新的文章发布到公众号平台上,平台会把内容推送给那些关注了TechFlow的用户,大家正是因为关注了TechFlow才读到了这篇文章。

所以在订阅制的内容平台当中,其实是一个三方关系,而不是读者和作者两方关系,平台在当中起到了媒介的作用。只是很多时候作为读者,我们可能会忽略平台的存在。

既然存在三方关系,我们在实现相关逻辑的时候就需要把这三方剥离出来,单独实现各自的逻辑,这样代码的耦合性才最低,可以更加方便以后的拓展。

代码实现

订阅者模式其实没有太多内容需要讲,我们只需要记住一点,就是尽量让属于不同实体的代码逻辑分开,而不是耦合在一起就可以了,没有太多其他的门道。

我们先来看这个模式当中最简单的部分,也就是Publisher(作者)这个部分。对于作者而言,它是最简单的,因为它能做的事情非常少,就只有发布内容而已。当然一般现在也会有一些作者保护机制,比如说可以拉黑一些不喜欢的用户什么的,但这里我们不需要考虑那么多,只需要考虑基本功能就行了。对于作者而言,最基本的功能就是发布内容。

代码非常简单,就只有几行。

class Publisher:    def __init__(self, msg_center):        self.provider = msg_center    def publish(self, msg):        self.provider.notify(msg)

因为作者自身是没办法发布内容的,作者是把要发布的内容上传到平台,平台代替作者去发布的。体现在这个类当中就是我们调用了provider也就是平台去执行通知(notify)的操作,把新发布的内容推送到读者端。

读者端稍微复杂一点,因为读者不仅可以订阅,还可以取关,并且收到了消息之后还可以打开以及一些互动。这里我们把功能简化,就留下了三个最基本的功能,分别是关注、取关以及操作。

class Subscriber:    def __init__(self, name, msg_center):        self.name = name        self.provider = msg_center    def subscribe(self, msg):        self.provider.subscribe(msg, self)    def unsubscribe(self, msg):        self.provider.unsubscribe(msg, self)    def run(self, msg):        print('{} got {}'.format(self.name, msg))

从代码当中我们可以看到,�ͼ�,����读者端的操作其实也是和平台交互。平台是读者和作者之间的媒介,读者和作者之间不直接发生关联。这其实是非常不错的设计,如果关联和依赖很多,就会出现要开发新功能的时候畏手畏脚,会影响其他模块的情况发生。

最后,我们来看平台的部分,平台的部分其实也不复杂,只是用一个dict存储了读者和作者之间的订阅关系而已。其实这里没必要使用setdefault,使用defaultdict会更好。

class Provider:    def __init__(self):        self.msg_queue = []        self.subscribers = {}    def notify(self, msg):        self.msg_queue.append(msg)    def subscribe(self, msg, subscriber):        self.subscribers.setdefault(msg, []).append(subscriber)    def unsubscribe(self, msg, subscriber):        self.subscribers[msg].remove(subscriber)    def update(self):        # 遍历所有的作者        for msg in self.msg_queue:            # 遍历所有订阅了msg的读者进行推送            for sub in self.subscribers.get(msg, []):                sub.run(msg)        self.msg_queue = []

这里我把执行的测试代码也放上来,大家感兴趣可以自己试验一下。

if __name__ == '__main__':    message_center = Provider()    fftv = Publisher(message_center)    jim = Subscriber('jim', message_center)    jim.subscribe('cartoon')    jack = Subscriber('jack', message_center)    jack.subscribe('music')    gee = Subscriber('gee', message_center)    gee.subscribe('movie')    vani = Subscriber('vani', message_center)    vani.subscribe('movie')    fftv.publish('cartoon')    fftv.publish('music')    fftv.publish('ads')    fftv.publish('cartoon')    fftv.publish('cartoon')    fftv.publish('movie')    fftv.publish('blank')    message_center.update()

从代码层面来说,这个设计模式没有太多的难度,主要是一种解耦的思想。这一个思想很重要,在实际开发当中,我们决不能仅仅满足于实现产品经理的功能,因为产品经理往往是不懂这些系统之间架构和软件工程的。我们之所以需要设计模式只有30%的原因是为了更好的效率以及更简洁的代码,剩下70%的原因其实都是为了抵御日后功能需求的变化。

废话不多说了,今天的文章就到这里,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、在看、转发)

  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net