定义对象间的一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生改变时,会通知所有观察者对象,使它们能够自动更新自己。
2、核心思想
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
使用动机:
将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。
本模式适用情况:
(1)当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。
(2)当一个抽象模型有两个方面,其中一方面依赖于另一方面,这时用观察者模式可以将这两者封装在独立的对象中,使它们各自独立地改变和复用。
总结:
观察者模式所做的工作其实就是解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
本模式是依赖倒置原则的最佳体现!
设计原则:为了交互对象之间的松耦合设计而奋斗到底!
3、优缺点分析
GOOD:
定义了一种一对多的关系,让多个观察对象(公司员工)同时监听一个主题对象(秘书),主题对象状态发生变化时,会通知所有的观察者,使它们能够更新自己。
BAD:
尽管使用了“依赖倒置原则”,但是“抽象通知者”还是依赖于“抽象观察者”。而且每个具体观察者不一定是“更新”方法需要调用。
在.net中可通过事件委托方法,使得通知者和观察者之间根本就互相不知道。
4、标准UML图
解析:
Observer模式定义的是一种一对多的关系,一是指Subject类对象,多则是Observer类对象。当Subject类对象的状态发生变化的时候通知与之对应的Observer类对象们也去相应的更新状态,同时支持动态的添加和删除Observer对象的功能。
Observer模式的实现要点是:
(一)一般Subject类都是采用链表等容器来存放Observer对象
(二)抽取出Observer对象的一些公共属性形成Observer基类,而Subject类中保存的则是Observer类对象的指针(从而实现了Subject和具体的Observer解耦)
5、标准源码
/************************************************************************
* FileName : Observer.h
* Author : steven oyj (steven.oyj@gmail.com)
* Description : Observer模式的演示代码
* Time : 2010/5/21
************************************************************************/
#ifndef OBSERVER_H
#define OBSERVER_H
9:
#include <list>
11:
int STATE;
13:
class Observer;
15:
// Subject抽象基类,只需要知道Observer基类的声明就可以了
class Subject
18: {
public:
20: Subject() : m_nSubjectState(-1){}
virtual ~Subject();
22:
// 通知对象改变状态
// 新增对象
// 删除对象
26:
// 虚函数,提供默认的实现,派生类可以自己实现来覆盖基类的实现
// 设置状态
// 得到状态
30:
protected:
// 模拟保存Subject状态的变量
// 保存Observer指针的链表
34: };
35:
// Observer抽象基类
class Observer
38: {
public:
40: Observer() : m_nObserverState(-1){}
virtual ~Observer(){}
42:
// 纯虚函数,各个派生类可能有不同的实现
// 通知Observer状态发生了变化
void Update(Subject* pSubject) = 0;
46:
protected:
// 模拟保存Observer状态的变量
49: };
50:
// ConcreateSubject类,派生在Subject类
class ConcreateSubject
public Subject
54: {
public:
56: ConcreateSubject() : Subject(){}
virtual ~ConcreateSubject(){}
58:
// 派生类自己实现来覆盖基类的实现
// 设置状态
// 得到状态
62:
63: };
64:
// ConcreateObserver类派生自Observer
class ConcreateObserver
public Observer
68: {
public:
70: ConcreateObserver() : Observer(){}
virtual ~ConcreateObserver(){}
72:
// 虚函数,实现基类提供的接口
void Update(Subject* pSubject);
75: };
76:
#endif
/************************************************************************
* FileName : Observer.cpp
* Author : steven oyj (steven.oyj@gmail.com)
* Description : Observer模式的演示代码
* Time : 2010/5/21
************************************************************************/
#include <iostream>
#include <algorithm>
10:
/* --------------------------------------------------------------------
| Subject类成员函数的实现
|
----------------------------------------------------------------------*/
15:
void Subject::Attach(Observer *pObserver)
17: {
;
19:
20: m_ListObserver.push_back(pObserver);
21: }
22:
void Subject::Detach(Observer *pObserver)
24: {
25: std::list<Observer*>::iterator iter;
26: iter = std::find(m_ListObserver.begin(), m_ListObserver.end(), pObserver);
27:
if (m_ListObserver.end() != iter)
29: {
30: m_ListObserver.erase(iter);
31: }
32:
;
34: }
35:
void Subject::Notify()
37: {
;
39:
40: std::list<Observer*>::iterator iter1, iter2;
41:
for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
43: iter1 != iter2;
44: ++iter1)
45: {
this);
47: }
48: }
49:
void Subject::SetState(STATE nState)
51: {
;
53: m_nSubjectState = nState;
54: }
55:
56: STATE Subject::GetState()
57: {
;
return m_nSubjectState;
60: }
61:
62: Subject::~Subject()
63: {
64: std::list<Observer*>::iterator iter1, iter2, temp;
65:
for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
67: iter1 != iter2;
68: )
69: {
70: temp = iter1;
71: ++iter1;
delete (*temp);
73: }
74:
75: m_ListObserver.clear();
76: }
77:
/* --------------------------------------------------------------------
| ConcreateSubject类成员函数的实现
|
----------------------------------------------------------------------*/
void ConcreateSubject::SetState(STATE nState)
83: {
;
85: m_nSubjectState = nState;
86: }
87:
88: STATE ConcreateSubject::GetState()
89: {
;
return m_nSubjectState;
92: }
93:
/* --------------------------------------------------------------------
| ConcreateObserver类成员函数的实现
|
----------------------------------------------------------------------*/
void ConcreateObserver::Update(Subject* pSubject)
99: {
if (NULL == pSubject)
return;
102:
103: m_nObserverState = pSubject->GetState();
104:
<< m_nObserverState << std::endl;
106: }
/************************************************************************
* FileName : Main.cpp
* Author : steven oyj (steven.oyj@gmail.com)
* Description : Observer模式的测试代码
* Time : 2010/5/21
************************************************************************/
#include <iostream>
9:
int main()
11: {
new ConcreateObserver;
new ConcreateObserver;
14:
new ConcreateSubject;
16: p->Attach(p1);
17: p->Attach(p2);
18: p->SetState(4);
19: p->Notify();
20:
21: p->Detach(p1);
22: p->SetState(10);
23: p->Notify();
24:
delete p;
26:
);
28:
return 0;
30: }