观察者模式(发布--订阅模式)定义了一种一对多的依赖关系,让多个观察着对象同时监听某一个主体对象。这个主体对象在状态发生变化时会通知所有观察者对象,使它们能够自动更新。
例子中介绍了同事上班时间炒股,让前台把风的例子。它很好的体现了依赖倒转原则,针对抽象编程而不针对具体的类,降低了程序的耦合性。秘书类和老板类均继承自通知类,炒股和看NBA类继承自观察类。
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class Observer
{
public:
string name;
public:
Observer(string n)
{
name=n;
}
virtual void update()
{
};
};
class Noticer
{
public:
vector<Observer*> observers;
string notice;
public:
Noticer()
{
notice="";
}
void attach(Observer *ob)
{
observers.push_back(ob);
}
void detach(string name)
{
for(int i=0;i<observers.size();i++)
{
//if(observers[i]->name=name)
{
// observers.erase(i);
}
}
}
void notify()
{
for(int i=0;i<observers.size();i++)
{
cout<<notice<<": ";
observers[i]->update();
}
}
};
class Boss :public Noticer
{
public:
Boss()
: Noticer()
{
notice="老子回来了,你们都在干嘛!!";
}
};
class Secretary:public Noticer
{
public:
Secretary()
{
notice="老板回来了";
}
};
class StockObserver:public Observer
{
public:
StockObserver(string n)
:Observer(n)
{
}
virtual void update()
{
cout<<name<<"关闭炒股软件,开始工作!"<<endl;
}
};
class NBAObserver:public Observer
{
public:
NBAObserver(string n)
:Observer(n)
{
}
virtual void update()
{
cout<<name<<"关闭NBA播放器,开始工作"<<endl;
}
};
int main(int argc,char**argv)
{
Secretary sc;
StockObserver stock1("张三");
StockObserver stock2("李四");
NBAObserver nba1("王五");
NBAObserver nba2("赵六");
sc.attach(&stock1);
sc.attach(&stock2);
sc.attach(&nba1);
sc.attach(&nba2);
sc.detach(nba2.name);
sc.notify();
Boss bs;
StockObserver stock3("倒霉蛋");
bs.attach(&stock3);
bs.notify();
return 0;
}
将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望在维持一致性时使各类紧密耦合,这样会给维护、扩展和重用都带来不便。当一个对象的改变需要改变其他对象时,并且它不知道需要改变多少具体的对象时,应该考虑使用观察者模式。
观察者模式的工作其实是在解除耦合,让耦合的双方都依赖于抽象而不依赖于具体。从而是各自的变化不会影响到其它。
《大话设计模式》在之后介绍了C#中的委托,C++中没有听过这个概念。还有接口与抽象类的区别,这都是我不熟悉的,暂时先放在这儿。以后解决。