意图:

        定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。

适用性:

        当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。

        当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。

        当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的


我们来举一个博客的例子,博主写好了一篇博文,发布之后有两个读者在阅读博文,当博主发现一些博文需要修改,修改之后重新发布,那么正在阅读的两个读者应该都能都到通知多好!下面就按照上面uml图来实现这样的一个例子:

#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std;

class Observer
{
public:
Observer(){}
virtual ~Observer(){}
virtual void Update(){};
};

class Blog
{
public:
Blog(){}
virtual ~Blog(){}

void Attach(Observer* observer)
{
vec_observer.push_back(observer);
}

void Romve(Observer* observer)
{
vector<Observer*>::iterator iter;
for (iter = vec_observer.begin(); iter != vec_observer.end(); ++iter)
{
if ((*iter) == observer)
vec_observer.erase(iter);
}
}

void Notify()
{
vector<Observer*>::iterator iter;
for (iter = vec_observer.begin(); iter != vec_observer.end(); ++iter)
{
(*iter)->Update();
}
}

virtual void SetStatus(string sts){}
virtual string GetStatus() { return m_status; };

private:
vector<Observer*> vec_observer;
protected:
string m_status;
};

class ConcreteBlog :public Blog
{
public:
ConcreteBlog(string name):m_blog_name(name){}
~ConcreteBlog(){}

void SetStatus(string sts)
{
m_status = "csdn通知: " + m_blog_name + sts;
}

string GetStatus()
{
return m_status;
}

private:
string m_blog_name;
};

class ConcreteObserver :public Observer
{
private:
string m_observer_name;
Blog *m_blog;
public:
ConcreteObserver(string name, Blog* blog) :m_observer_name(name), m_blog(blog){}
~ConcreteObserver(){}

void Update()
{
string status = m_blog->GetStatus();
cout << m_observer_name << "-----------" << status << endl;
}
};

int main()
{
Blog *blog = new ConcreteBlog("chenxun");
Observer *ob1 = new ConcreteObserver("xiaowang", blog);
Observer *ob2 = new ConcreteObserver("xiaozhang", blog);
blog->Attach(ob1);
blog->Attach(ob2);
blog->SetStatus("发表了新博客");
blog->Notify();

delete blog;
delete ob1;
delete ob2;

return 0;
}