一、简介
1、观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化的时候,会通知所有观察者对象,使它们能够动态的更新自己。
如:图形界面的工具箱中,表格对象和柱状图对象使用不同的形式描述同一应用数据对象的信息。表格对象和柱状图对象相互并不知道对方的存在,但是当用户改变表格中的信息的时候,柱状图也应该立即反映这一变化,反过来也如此。这意味着表格对象和柱状图对象都依赖于数据对象,数据对象的任何改变都应该立即通知它们。所以这个例子中表格和柱状图就是两个观察者,而数据对象就是被观察的主题。
2、模式中的角色
抽象主题(Subject):它把所有观察者对象的引用保存到一个List,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
3、UML
4、所属类别:行为型
二、C++程序
下面以老师上课点名为例写一个观察者的程序,小尹和小胥两位同学都要一个去上课的同学帮忙老师是否点名,如果点名了就跑去上课,否则泡实验室学习。
1 // 观察者模式.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include<iostream> 6 #include <list> 7 #include<string> 8 using namespace std; 9 class Observer 10 { 11 public: 12 Observer(){} 13 virtual ~Observer(){} 14 virtual void update(){} 15 }; 16 //抽象主题 17 class Subject 18 { 19 private: 20 typedef list<Observer* >LIST; //观察者链表 21 LIST observers; 22 protected: 23 string subjectstate; 24 public: 25 Subject(){} 26 virtual ~Subject(){} 27 void add_observer(Observer *observer) //添加观察者 28 { 29 observers.push_back(observer); 30 } 31 void remove_observer(Observer *observer)//删除观察者 32 { 33 observers.remove(observer); 34 } 35 virtual void set_subjectstate(string )=0;//设置当前主题的状态 36 virtual string get_subjectstate()=0;//观察当前主题的状态 37 void notify() 38 { 39 LIST::iterator node = observers.begin(); 40 for(; node != observers.end(); node++) 41 { 42 (*node)->update(); 43 } 44 } 45 }; 46 47 class Concretesubject:public Subject 48 { 49 public: 50 Concretesubject (){} 51 virtual~Concretesubject (){} 52 virtual void set_subjectstate(string s) 53 { 54 subjectstate=s; 55 } 56 virtual string get_subjectstate() 57 { 58 return subjectstate; 59 } 60 }; 61 62 class Concereteobserver:public Observer 63 { 64 private: 65 Subject * subject; 66 public: 67 Concereteobserver(Subject *s) 68 { 69 subject=s; 70 } 71 ~Concereteobserver(){} 72 void update() 73 { 74 string state=subject->get_subjectstate(); 75 if(state=="点名了") 76 { 77 cout<<"赶紧跑去上课"<<endl; 78 } 79 if(state=="正常上课") 80 { 81 cout<<"继续泡实验室"<<endl; 82 } 83 } 84 }; 85 int _tmain(int argc, _TCHAR* argv[]) 86 { 87 //创建一个具体的主题,上课老师是否点名 88 Subject *dianming=new Concretesubject(); 89 //创造两个人 小尹和小胥 90 Observer * xiaoyin=new Concereteobserver(dianming); 91 Observer * xiaoxu=new Concereteobserver(dianming); 92 //将小尹和小胥两个人注册为该主题的观察者 93 dianming->add_observer(xiaoyin); 94 dianming->add_observer(xiaoxu); 95 //该主题发生变化的时候,自动通知他们,然后他们采取措施 96 dianming->set_subjectstate("点名了"); 97 dianming->notify(); 98 return 0; 99 }