设计模式其实最常用在面向对象编程中,如果通俗的说,他是软件开发中的一种思想,根据这种思想我们可以设计出来的软件更加优秀,同时软件之间更容易进行扩展。
发布订阅者模式是其中的一种思想,是对显示中的一种场景的抽象,常见的场景有微信公众号订阅,朋友圈推送,群消息推送等,都或多或少用了这种设计模式。
发布订阅者模式又称为观察者模式,对象的大概关系如下:
其中涉及四个对象:
我们简单来看一下其中各个对象的意义。
首先我们拿公众号订阅为例, 那么发布这个内容的是公众号的号主,他要把文章发送给每个订阅他公众号的人。
所以被观察的人或者说发布文章的人是不是需要一个对象(图中的 subject),那么订阅公众号的人也是需要一个对象(concrete observer),那么我是不是还需要一个中介来让两者发生关系,或者说来通知订阅的人(concrete subject)。
到这里可能会有人说,不对呀,不是有四个对象吗?那我想,如果有人订阅了我的公众号,但是这个人每次发布文章都会来杠一下,我把他拉黑了,那么他虽然订阅了我的公众号,我还是不会给他发送通知,所以我们是不是订阅者有各种各样的类型。
想到各种各样类型,是不是就是面向对象里边的多态了,那我是不是要有一个接口,这就是 observer。
我们就以公众号订阅模式实现这个代码。
首先就是订阅者其实是多种多样的,因此我们需要写一个订阅者的接口。
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; //获取是否在黑名单上
};
由于提前引入了发布者的类因此先声明,然后定义,也可以先定义,这里是为了讲述真个发布订阅设计模式的一个逻辑。
订阅者的接口已经定义好了,然后就是发布者的一个定义。
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 集合来添加订阅者集合
};
上述实现比较简单,然后我们需要定义具体的订阅者了。
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;
};
然后就是通知订阅者的中介实现了,其代码如下:
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 删除。