您的位置:首页 > 其它

(十)观察者模式

2016-02-22 14:24 417 查看
描述:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。【DP】

UML类图:



具体源码如下:

// Observer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <memory>
#include <list>
#include <string>

using namespace std;

/*
Subject(主题或抽象通知者)类,一般使用一个抽象类或者一个接口实现,
它包含一个观察者对象的集合,每个主题都可以有任意数量的观察者。
抽象主题提供可以增加和删除观察者的接口。
*/
class Observer
{
public:
virtual ~Observer(){}
virtual void Update() = 0;
};

//被观察者
class Subject
{
public:
virtual ~Subject(){}
private:
list<Observer *> m_ob;
public:
//增加观察者
void Attach(Observer *pob)
{
m_ob.push_back(pob);
}
//删除观察者
void Detach(Observer *pob)
{
m_ob.remove(pob);
}
//通知
void Notify()
{
auto it = m_ob.cbegin();
for (; it != m_ob.cend(); ++it)
{
(*it)->Update();
}
}
};

//具体的被观察者
class ConcreteSubject : public Subject
{
private:
//被观察者状态
string subjectState;
public:
void SetSubjectState(const string &str)
{
subjectState = str;
}
string GetSubjectState()
{
return subjectState;
}
};

//具体观察者
class ConcreteObserver : public Observer
{
private:
string name;
string observerState;
ConcreteSubject * subject;
public:
ConcreteObserver(ConcreteSubject * subject, string name)
{
this->subject = subject;
this->name = name;
}
void Update()
{
observerState = subject->GetSubjectState();
cout << "观察者(" << name << ")的新状态是(" << observerState << ")。" << endl;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
ConcreteSubject *s = new ConcreteSubject();
s->Attach(new ConcreteObserver(s, "X"));
s->Attach(new ConcreteObserver(s, "Y"));
s->Attach(new ConcreteObserver(s, "Z"));

s->SetSubjectState("ABC");
s->Notify();

return 0;
}


运行结果:



应用场景:

1.当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待更新时,应该考虑使用观察者模式。

特点:

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

总结:观察者模式所做的工作就是在解耦。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化不会影响另一边的变化,其实就是依赖倒转原则。上面代码中的ConcreteObserver类和ConcreteSubject类没有必要知道对象,在基类层就已经把耦合做好了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: