观察者模式(发布-订阅模式)
定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
本文介绍观察者模式代码框架,代码使用C++语言描述,代码存在的不足或问题有望各位指出。
(1)观察者模式代码框架
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//观察者模式
class Observer;
class Subject
{
public:
Subject(){}
virtual ~Subject(){}
virtual void attach(Observer *observer)
{
observers.push_back(observer);
}
virtual void detach(Observer *observer)
{
//删除特定的observer
auto it = observers.begin();
for(;it!=observers.end();++it)
{
if (*it == observer)
break;
}
if(it!=observers.end())
observers.erase(it);
}
virtual void notify();
private:
vector<Observer*>observers;
};
class Observer
{
public:
Observer(){}
virtual ~Observer(){}
virtual void update() = 0;
};
void Subject::notify()
{
for(auto it=observers.begin();it!=observers.end();++it)
{
(*it)->update();
}
}
class ConcreteSubject : public Subject
{
public:
string get()
{
return subjectState;
}
void set(string value)
{
subjectState = value;
}
private:
string subjectState;
};
class ConcreteObserver : public Observer
{
public:
ConcreteObserver(ConcreteSubject *sub,string name):sub(sub),name(name)
{}
void update() override
{
cout << "观察者" << name << "的新状态是" << sub->get() << endl;
}
private:
ConcreteSubject *sub;
string name;
string observerState;
};
int main()
{
ConcreteSubject *s = new ConcreteSubject();
s->attach(new ConcreteObserver(s, "X"));
s->attach(new ConcreteObserver(s, "Y"));
s->attach(new ConcreteObserver(s, "Z"));
s->set("ABC");
s->notify();
delete s;
return 0;
}
(2) 双向耦合的代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class StockObserver;
class Secretary
{
public:
Secretary(){}
void attach(StockObserver *observer); //类或结构体的前向声明只能用来定义指针对象或引用
void notify();
string get();
void set(string action);
private:
vector<StockObserver*> observers;
string action;
};
void Secretary::attach(StockObserver *observer) //类或结构体的前向声明只能用来定义指针对象或引用
{
observers.push_back(observer);
}
string Secretary::get()
{
return action;
}
void Secretary::set(string action)
{
this->action = action;
}
class StockObserver
{
public:
StockObserver(){}
StockObserver(string name, Secretary *sub)
{
this->name = name;
this->sub = sub;
}
void update();
private:
string name;
Secretary *sub;
};
void StockObserver::update()
{
string out = sub->get();
cout << out << " " << name << "关闭股票行情,继续工作!" << endl;
}
void Secretary::notify()
{
for (auto it = observers.begin(); it != observers.end(); it++)
{
(*it)->update();
}
}
int main ()
{
Secretary *tongzizhe = new Secretary();
StockObserver *tongshi1 = new StockObserver("liu", tongzizhe);
StockObserver *tongshi2 = new StockObserver("chao", tongzizhe);
tongzizhe->attach(tongshi1);
tongzizhe->attach(tongshi2);
tongzizhe->set("老板回来了!");
//通知两个同事
tongzizhe->notify();
delete tongzizhe;
delete tongshi1;
delete tongshi2;
return 0;
}
(3)解耦合实践一
//解耦合实践一
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Secretary;
class Observer
{
public:
Observer(){}
virtual ~Observer(){}
Observer(string name, Secretary *sub)
{
this->name = name;
this->sub = sub;
}
virtual void update() = 0;
protected:
string name;
Secretary *sub;
};
class StockObserver : public Observer
{
public:
StockObserver(string name, Secretary *sub)
{
this->name = name;
this->sub = sub;
}
void update() override;
};
class NBAObserver: public Observer
{
public:
NBAObserver(string name,Secretary *sub)
{
this->name = name;
this->sub = sub;
}
void update() override;
};
class Secretary
{
public:
void attach(Observer *observer)
{
observers.push_back(observer);
}
void detach(Observer *observer)
{
//删除特定的observer
auto it = observers.begin();
for(;it!=observers.end();++it)
{
if (*it == observer)
break;
}
if(it!=observers.end())
observers.erase(it);
}
void notify()
{
for(auto it =observers.begin(); it != observers.end();++it)
{
(*it)->update();
}
}
string get()
{
return action;
}
void set(string value)
{
action = value;
}
private:
vector<Observer *>observers;
string action;
};
void StockObserver::update()
{
cout << sub->get() << " " << name << " " << "关闭股票行情,继续工作!" << endl;
}
void NBAObserver::update()
{
cout << sub->get() << " " << name << " " << "关闭NBA直播,继续工作!" << endl;
}
int main()
{
Secretary *tongzizhe = new Secretary();
Observer *tongshi1 = new StockObserver("liu", tongzizhe);
Observer *tongshi2 = new NBAObserver("chao", tongzizhe);
tongzizhe->attach(tongshi1);
tongzizhe->attach(tongshi2);
tongzizhe->set("老板回来了!");
//通知两个同事
tongzizhe->notify();
delete tongzizhe;
delete tongshi1;
delete tongshi2;
return 0;
}
(4) 解耦合实践二
//解耦合实践二
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Observer;
class Subject
{
public:
Subject(){}
virtual ~Subject(){}
virtual void attach(Observer *observer) =0;
virtual void detach(Observer *observer) =0;
virtual void notify() =0;
virtual string get() =0;
virtual void set(string value) =0;
};
class Boss : public Subject
{
public:
void attach(Observer *observer) override
{
observers.push_back(observer);
}
void detach(Observer *observer) override
{
//删除特定的observer
auto it = observers.begin();
for(;it!=observers.end();++it)
{
if (*it == observer)
break;
}
if(it!=observers.end())
observers.erase(it);
}
void notify() override;
string get() override
{
return action;
}
void set(string value) override
{
action = value;
}
private:
vector<Observer*>observers;
string action;
};
class Secretary : public Subject
{
public:
void attach(Observer *observer) override
{
observers.push_back(observer);
}
void detach(Observer *observer) override
{
//删除特定的observer
auto it = observers.begin();
for(;it!=observers.end();++it)
{
if (*it == observer)
break;
}
if(it!=observers.end())
observers.erase(it);
}
void notify() override;
string get() override
{
return action;
}
void set(string value) override
{
action = value;
}
private:
vector<Observer *>observers;
string action;
};
class Observer
{
public:
Observer(){}
virtual ~Observer(){}
Observer(string name, Subject *sub)
{
this->name = name;
this->sub = sub;
}
virtual void update() = 0;
protected:
string name;
Subject *sub;
};
class StockObserver : public Observer
{
public:
StockObserver(string name, Subject *sub)
{
this->name = name;
this->sub = sub;
}
void update() override;
};
class NBAObserver: public Observer
{
public:
NBAObserver(string name,Subject *sub)
{
this->name = name;
this->sub = sub;
}
void update() override;
};
void StockObserver::update()
{
cout << sub->get() << " " << name << " " << "关闭股票行情,继续工作!" << endl;
}
void NBAObserver::update()
{
cout << sub->get() << " " << name << " " << "关闭NBA直播,继续工作!" << endl;
}
void Boss::notify()
{
for(auto it =observers.begin(); it != observers.end();++it)
{
(*it)->update();
}
}
void Secretary::notify()
{
for(auto it =observers.begin(); it != observers.end();++it)
{
(*it)->update();
}
}
int main()
{
Subject *chaochao = new Boss();
Observer *tongshi1 = new StockObserver("liu", chaochao);
Observer *tongshi2 = new NBAObserver("chao", chaochao);
chaochao->attach(tongshi1);
chaochao->attach(tongshi2);
//chaochao->detach(tongshi1);
chaochao->set("我超超回来了!");
chaochao->notify();
delete chaochao;
delete tongshi1;
delete tongshi2;
return 0;
}
观察者模式特点
1、将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。
2、当一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。一个抽象模型有两个方面,其中一方面依赖于另一方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立
3、观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。