前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式之发布订阅者模式

设计模式之发布订阅者模式

原创
作者头像
ge3m0r
发布2024-05-01 17:44:09
1170
发布2024-05-01 17:44:09

设计模式简述

设计模式其实最常用在面向对象编程中,如果通俗的说,他是软件开发中的一种思想,根据这种思想我们可以设计出来的软件更加优秀,同时软件之间更容易进行扩展。

发布订阅者模式是其中的一种思想,是对显示中的一种场景的抽象,常见的场景有微信公众号订阅,朋友圈推送,群消息推送等,都或多或少用了这种设计模式。

发布订阅者模式

发布订阅者模式又称为观察者模式,对象的大概关系如下:

图片来自书籍《研磨设计模式》
图片来自书籍《研磨设计模式》

其中涉及四个对象:

我们简单来看一下其中各个对象的意义。

首先我们拿公众号订阅为例, 那么发布这个内容的是公众号的号主,他要把文章发送给每个订阅他公众号的人。

所以被观察的人或者说发布文章的人是不是需要一个对象(图中的 subject),那么订阅公众号的人也是需要一个对象(concrete observer),那么我是不是还需要一个中介来让两者发生关系,或者说来通知订阅的人(concrete subject)。

到这里可能会有人说,不对呀,不是有四个对象吗?那我想,如果有人订阅了我的公众号,但是这个人每次发布文章都会来杠一下,我把他拉黑了,那么他虽然订阅了我的公众号,我还是不会给他发送通知,所以我们是不是订阅者有各种各样的类型。

想到各种各样类型,是不是就是面向对象里边的多态了,那我是不是要有一个接口,这就是 observer。

代码实现

我们就以公众号订阅模式实现这个代码。

首先就是订阅者其实是多种多样的,因此我们需要写一个订阅者的接口。

代码语言:c++
复制
class Publisher;
class SubscriberObserver
{
public:
    SubscriberObserver(){}
    virtual ~SubscriberObserver(){}
    virtual void update(PublisherSubject *publisher) = 0; //被观察对象更新操作

    virtual void setStatus(bool inblacklist) = 0; //设置是否在黑名单上

    virtual string getStatus(bool inblacklist) = 0; //获取是否在黑名单上
};

由于提前引入了发布者的类因此先声明,然后定义,也可以先定义,这里是为了讲述真个发布订阅设计模式的一个逻辑。

订阅者的接口已经定义好了,然后就是发布者的一个定义。

代码语言:c++
复制
class PublisherSubject {
public:
    PublisherSubject(){}
    virtual ~PublisherSubject(){}
    void attach(SubscriberObserver *subscriber) {
        subscribers.push_back(subscriber);  //添加订阅者
    }
    void detach(SubscriberObserver *subscriber) {
        subscribers.remove(subscriber);     //移除订阅者
    }
    virtual void notifySubscriber() = 0;  //用来通知订阅者
protected:

    list<SubscriberObserver *> subscribers; //这里使用 list 集合来添加订阅者集合
};

上述实现比较简单,然后我们需要定义具体的订阅者了。

代码语言:c++
复制
class Subscriber: public SubscriberObserver
{
public:
    Subscriber(){}
    virtual ~Subscriber(){}
    string getStatus() {
        return inblacklist;
    }

    void setStatus(bool blacklist) {
        inblacklist = blacklist;
    }
    string getName(){
        return m_name;
    }

    void setName(sting name) {
        m_name= name;
    }

    virtual void update() {
        //这里采用的是拉的方式
        cout << m_name << " 获取到通知"  <<endl;
    }
private:
    bool inblacklist;
    string m_name;
};

然后就是通知订阅者的中介实现了,其代码如下:

代码语言:c++
复制
class Publisher: public PublisherSubject
{
public:
    Publisher(){}
    virtual ~Publisher(){}
    
    virtual void setPublished(bool pushlished) {
        m_published = pushlished;
        //通知相应的观察者
        notifyWatchers();
    }

    /**
     * 通知相应的观察者对象
     */
    virtual void notifyWatchers() {
        //循环所有注册的观察者
        for(SubscriberObserver *subscribers : subscriber){
            if(pushlished){. //判断是否在黑名单,如果不在就发送通知.
                if(!subscriber->getStatus()) subscriber->update(this);
            }
        }
    }
private:
    int m_pushlished = 0;  //默认没有发布
};

至此,一个简单的公众号的订阅和发布者模式就实现好了,总体来说比较简单。

另外在简单说一下拉模式和推模式,一般人听到这个就是在 kafka 里边的一种,其实就是消息的主导权在谁手里,如果在订阅者手里,那么就是我只是获取通知,不会获取其中内容,如果需要内容我再获取。而推模式主动权在发布者模式中,我不管你要不要,我就要把具体内容推送给你。具体实现就不做了,两者差异不大。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 设计模式简述
  • 发布订阅者模式
  • 代码实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com