概述
在软件工程中,设计模式(Design Pattern)是对软件设计普遍存在(反复出现)的各种问题,锁提出的解决防范。根据模式的目的来划分的话,GoF(Gang of Four) 设计模式可以分为以下三种类型:
1.创建型模式:用来描述“如何创建对象”,它的主要特点是“将对象的创建和使用分离”。包括单例、原型、工厂方法、抽象工厂和建造者5种模式。
2.结构型模式:用来描述如何将类或对象按照某种布局组成更大的结构。包括代理、适配器、侨接、装饰、外观、享元和组合7种模式。
3.行为型模式:用来识别对象之间的常用交流模式以及如何分配职责。包括模版方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录和解释器11种模式。
今天介绍1种常用的设计模式。
观察者模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使他们能够更新自己。
在观察者模式中有连个主要的角色:Subject(主题,被观察对象)和Observer(观察者)
被观察对象自身应该包含一个容器来存放观察者对象,当被观察者自身发生改变时通知容器内所有的观察者对象自动更新。
观察者对象可以注册到被观察者的中,完成注册后可以检测被观察者的变化,接收被观察者的通知。当然观察者也可以被注销换掉,停止对被观察者的监控。
/*
关键代码:在目标类中增加一个ArrayList存放观察者们。
*/
#include <iostream>
#include <list>
#include <memory>
using namespace std;
class View;
//被观察者抽象类 数据模型
class DataModel {
public:
virtual ~DataModel(){}
virtual void addView(View *view) = 0;
virtual void removeView(View* view) = 0;
virtual void notif() = 0; //通知函数
};
//观察者抽象类 视图
class View {
public:
virtual ~View() {
cout << "~View()" << endl;
}
virtual void update() = 0;
virtual void setViewName(const string& name) = 0;
virtual const string& name() = 0;
}
//具体的被观察类,整数模型
class IntDataModel:public DataModel {
public:
~IntDataModel() {
m_pViewList.clear();
}
virtual void addView(View *view) override {
shared_ptr<View> temp(view);
auto iter = find(m_pViewList.begin(), m_pViewList.end(), temp);
if (iter == m_pViewList.end()) {
m_pViewList.push_font(temp);
}
else {
cout << "View already exists" <<endl;
}
}
}
void removeView(View* view) override {
auto iter = m_pViewList.begin();
for(;iter != m_pViewList.end(); iter++) {
if((*iter).get() == view) {
m_pViewList.erase(iter);
cout << "remove view" << endl;
return ;
}
}
}
virtual void notify() override {
auto iter = m_pViewList.begin();
for(; iter != m_pViewList.end(); iter++) {
(*iter).get()->update();
}
}
private:
list<shared_ptr<View>> m_pViewList;
};
//具体的观察者类 表视图
class TableView : public View {
public:
TableView() ; m_name("unknow"){}
TableView(const string& name) : m_name(name){}
~TableView(){
cout << "~TableView():" << m_name.data() << endl;
}
void setViewName(const string& name) {
m_name = name;
}
const string& name() {
return m_name;
}
void update() override {
cout << m_name.data() << " update" << endl;
}
private:
string m_name;
};
int main() {
/*
补充说明,在本次代码示例中,View一旦被注册到DataModel类之后,DataModel解析时会自动解析调
内部容器中存储的View对象,因此注册后的View对象不需要在手动去delete,再去delete View对象会出错
*/
View *v1 = new TableView("TableView1");
View *v2 = new TableView("TableView2");
View *v3 = new TableView("TableView3");
View *v4 = new TableView("TableView4");
IntDataModel* model = new IntDataModel;
model->addView(v1);
model->addView(v2);
model->addView(v3);
model->addView(v4);
model->notify();
cout<<"---------------n"<<endl;
model->removeView(v1);
model->notify();
delete model;
model = nullptr;
return 0;
}
应用场景:
一个对象的行为依赖于另一个对象的状态。换一种方法,当被观察对象(目标对象)的状态发生改变时,会直接影响到观察对象的行为。
发布订阅模式
在软件架构中,发布/订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息发分为不同的类别,然后分别发送给不同的订阅者。同样的,订阅者可以表达对一个或多个类别的兴趣,只接受感兴趣的消息,无需了解哪些发布存在。
在发布订阅模式中有三个主要角色:Publisher(发布者)、Channels(通道)和Subscriber(订阅者)
可以理解为发布者主动发出特定的通道,观察者接收自己想要的。
最后
以上就是乐观芝麻为你收集整理的C++设计模式之观察者模式和发布订阅模式的全部内容,希望文章能够帮你解决C++设计模式之观察者模式和发布订阅模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复