1、意图
定义对象间的一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生改变时,会通知所有观察者对象,使它们能够自动更新自己。
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、标准源码
1: /************************************************************************
2: * FileName : Observer.h
3: * Author : steven oyj (steven.oyj@gmail.com)
4: * Description : Observer模式的演示代码
5: * Time : 2010/5/21
6: ************************************************************************/
7: #ifndef OBSERVER_H
8: #define OBSERVER_H
9:
10: #include <list>
11:
12: typedef int STATE;
13:
14: class Observer;
15:
16: // Subject抽象基类,只需要知道Observer基类的声明就可以了
17: class Subject
18: {
19: public:
20: Subject() : m_nSubjectState(-1){}
21: virtual ~Subject();
22:
23: void Notify(); // 通知对象改变状态
24: void Attach(Observer *pObserver); // 新增对象
25: void Detach(Observer *pObserver); // 删除对象
26:
27: // 虚函数,提供默认的实现,派生类可以自己实现来覆盖基类的实现
28: virtual void SetState(STATE nState); // 设置状态
29: virtual STATE GetState(); // 得到状态
30:
31: protected:
32: STATE m_nSubjectState; // 模拟保存Subject状态的变量
33: std::list<Observer*> m_ListObserver; // 保存Observer指针的链表
34: };
35:
36: // Observer抽象基类
37: class Observer
38: {
39: public:
40: Observer() : m_nObserverState(-1){}
41: virtual ~Observer(){}
42:
43: // 纯虚函数,各个派生类可能有不同的实现
44: // 通知Observer状态发生了变化
45: virtual void Update(Subject* pSubject) = 0;
46:
47: protected:
48: STATE m_nObserverState; // 模拟保存Observer状态的变量
49: };
50:
51: // ConcreateSubject类,派生在Subject类
52: class ConcreateSubject
53: : public Subject
54: {
55: public:
56: ConcreateSubject() : Subject(){}
57: virtual ~ConcreateSubject(){}
58:
59: // 派生类自己实现来覆盖基类的实现
60: virtual void SetState(STATE nState); // 设置状态
61: virtual STATE GetState(); // 得到状态
62:
63: };
64:
65: // ConcreateObserver类派生自Observer
66: class ConcreateObserver
67: : public Observer
68: {
69: public:
70: ConcreateObserver() : Observer(){}
71: virtual ~ConcreateObserver(){}
72:
73: // 虚函数,实现基类提供的接口
74: virtual void Update(Subject* pSubject);
75: };
76:
77: #endif
1: /************************************************************************
2: * FileName : Observer.cpp
3: * Author : steven oyj (steven.oyj@gmail.com)
4: * Description : Observer模式的演示代码
5: * Time : 2010/5/21
6: ************************************************************************/
7: #include "Observer.h"
8: #include <iostream>
9: #include <algorithm>
10:
11: /* --------------------------------------------------------------------
12: | Subject类成员函数的实现
13: |
14: ----------------------------------------------------------------------*/
15:
16: void Subject::Attach(Observer *pObserver)
17: {
18: std::cout << "Attach an Observer\n";
19:
20: m_ListObserver.push_back(pObserver);
21: }
22:
23: void Subject::Detach(Observer *pObserver)
24: {
25: std::list<Observer*>::iterator iter;
26: iter = std::find(m_ListObserver.begin(), m_ListObserver.end(), pObserver);
27:
28: if (m_ListObserver.end() != iter)
29: {
30: m_ListObserver.erase(iter);
31: }
32:
33: std::cout << "Detach an Observer\n";
34: }
35:
36: void Subject::Notify()
37: {
38: std::cout << "Notify Observers's State\n";
39:
40: std::list<Observer*>::iterator iter1, iter2;
41:
42: for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
43: iter1 != iter2;
44: ++iter1)
45: {
46: (*iter1)->Update(this);
47: }
48: }
49:
50: void Subject::SetState(STATE nState)
51: {
52: std::cout << "SetState By Subject\n";
53: m_nSubjectState = nState;
54: }
55:
56: STATE Subject::GetState()
57: {
58: std::cout << "GetState By Subject\n";
59: return m_nSubjectState;
60: }
61:
62: Subject::~Subject()
63: {
64: std::list<Observer*>::iterator iter1, iter2, temp;
65:
66: for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
67: iter1 != iter2;
68: )
69: {
70: temp = iter1;
71: ++iter1;
72: delete (*temp);
73: }
74:
75: m_ListObserver.clear();
76: }
77:
78: /* --------------------------------------------------------------------
79: | ConcreateSubject类成员函数的实现
80: |
81: ----------------------------------------------------------------------*/
82: void ConcreateSubject::SetState(STATE nState)
83: {
84: std::cout << "SetState By ConcreateSubject\n";
85: m_nSubjectState = nState;
86: }
87:
88: STATE ConcreateSubject::GetState()
89: {
90: std::cout << "GetState By ConcreateSubject\n";
91: return m_nSubjectState;
92: }
93:
94: /* --------------------------------------------------------------------
95: | ConcreateObserver类成员函数的实现
96: |
97: ----------------------------------------------------------------------*/
98: void ConcreateObserver::Update(Subject* pSubject)
99: {
100: if (NULL == pSubject)
101: return;
102:
103: m_nObserverState = pSubject->GetState();
104:
105: std::cout << "The ObeserverState is " << m_nObserverState << std::endl;
106: }
1: /************************************************************************
2: * FileName : Main.cpp
3: * Author : steven oyj (steven.oyj@gmail.com)
4: * Description : Observer模式的测试代码
5: * Time : 2010/5/21
6: ************************************************************************/
7: #include "Observer.h"
8: #include <iostream>
9:
10: int main()
11: {
12: Observer *p1 = new ConcreateObserver;
13: Observer *p2 = new ConcreateObserver;
14:
15: Subject* p = 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:
25: delete p;
26:
27: system("pause");
28:
29: return 0;
30: }