设计模式(15) - Observer观察者模式
2013-12-22 00:11
429 查看
1. 意图
观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。2. UML类图
主题(subject)和观察者(observers)之间定义为了一对多的关系。多个观察者依赖于某个主题,这样当主题的状态发生改变时,观察者就会被通知到。得到通知后,观察者就能使用新的值进行更新。
3. 代码实现
例子1: GoF版本#include<iostream> #include<vector> #include<algorithm> #include<string.h> #include<time.h> using namespace std; class Subject; class Observer { public: Observer() {} ~Observer() {} virtual void Update(Subject *theChangeSubject) = 0; }; class Subject { public: Subject() {} virtual ~Subject() {} virtual void Attach(Observer *); virtual void Detach(Observer *); virtual void Notify(); private: vector<Observer *> _observers; }; void Subject::Attach(Observer *ob) { _observers.push_back(ob); } void Subject::Detach(Observer *ob) { vector<Observer*>::iterator pos = find(_observers.begin(), _observers.end(), ob); if (pos != _observers.end()) _observers.erase(pos); } void Subject::Notify() { for_each(_observers.begin(), _observers.end(), [this](Observer *element) { element->Update(this); }); } class ClockTimer :public Subject { public: ClockTimer() { _strtime_s(tmpbuf); } int GetHour(); int GetMinute(); int GetSecond(); void Tick(); private: char tmpbuf[128]; }; //根据TZ环境变量来设置时区。如果TZ没有被设置,则查询操作系统 //来获取默认值 void ClockTimer::Tick() { _tzset(); //获取系统风格的时间 _strtime_s(tmpbuf); Notify(); } int ClockTimer::GetHour() { char timebuf[128]; strncpy_s(timebuf, tmpbuf, 2); timebuf[2] = NULL; return atoi(timebuf); } int ClockTimer::GetMinute() { char timebuf[128]; strncpy_s(timebuf, tmpbuf + 3, 2); timebuf[2] = NULL; return atoi(timebuf); } int ClockTimer::GetSecond() { char timebuf[128]; strncpy_s(timebuf, tmpbuf + 6, 2); timebuf[2] = NULL; return atoi(timebuf); } class DigitalClock :public Observer { public: DigitalClock(ClockTimer *); ~DigitalClock(); void Update(Subject *); void Draw(); private: ClockTimer *_subject; }; DigitalClock::DigitalClock(ClockTimer *s) : _subject(s) { _subject->Attach(this); } DigitalClock::~DigitalClock() { _subject->Detach(this); } void DigitalClock::Update(Subject *theChangedSubject) { int hour = _subject->GetHour(); int minute = _subject->GetMinute(); int sec = _subject->GetSecond(); cout << "Digital time is " << hour << ":" << minute << ":" << sec << endl; } class AnalogClock :public Observer { public: AnalogClock(ClockTimer *); ~AnalogClock(); void Update(Subject *); void Draw(); private: ClockTimer *_subject; }; AnalogClock::AnalogClock(ClockTimer *s) : _subject(s) { _subject->Attach(this); } AnalogClock::~AnalogClock() { _subject->Detach(this); } void AnalogClock::Update(Subject *theChangedSubject) { if (theChangedSubject == _subject) Draw(); } void AnalogClock::Draw() { int hour = _subject->GetHour(); int minute = _subject->GetMinute(); int sec = _subject->GetSecond(); cout << "Analog time is " << hour << ":" << minute << ":" << sec << endl; } int main() { ClockTimer timer; DigitalClock dc(&timer); AnalogClock ac(&timer); timer.Tick(); return 0; }运行结果为:
Digital time is 20:9:14
Analog time is 20:9:14
例子2
与上一个例子不同之处在于,MySubject类与MyObserver类之间没有编译期间的依赖关系,而是在运行时动态创建的。
#include<iostream> #include<vector> #include<string> #include<algorithm> using namespace std; class Observer { public: virtual ~Observer(){} virtual void update(int message) = 0; }; class Subject { public: virtual ~Subject() {} virtual void subscribe(Observer *); virtual void unsubscribe(Observer *); virtual void notify(int message); private: vector<Observer*> _obsvList; }; void Subject::subscribe(Observer *ob) { _obsvList.push_back(ob); } void Subject::unsubscribe(Observer *ob) { vector<Observer*>::iterator pos = find(_obsvList.begin(), _obsvList.end(), ob); if (pos != _obsvList.end()) _obsvList.erase(pos); } void Subject::notify(int message) { for_each(_obsvList.begin(), _obsvList.end(), [message](Observer* element) { element->update(message); }); } class MySubject : public Subject { public: enum message { ADD, REMOVE }; }; class MyObserver : public Observer { public: explicit MyObserver(const string &str) :_name(str) {} void update(int message) { cout << _name << " got message: " << message << endl; } private: string _name; }; int main() { MyObserver obA("observerA"); MyObserver obB("observerB"); MyObserver obC("observerC"); MySubject sub; sub.subscribe(&obA); sub.subscribe(&obB); sub.subscribe(&obC); sub.subscribe(&obB); sub.notify(MySubject::ADD); sub.notify(MySubject::REMOVE); getchar(); return 0; }运行结果为:
observerA got message: 0
observerB got message: 0
observerC got message: 0
observerB got message: 0
observerA got message: 1
observerB got message: 1
observerC got message: 1
observerB got message: 1
相关文章推荐
- 设计模式(14) - State状态模式
- 安卓查询手机号码归属地webservice之get简洁版
- 设计模式(13) - Strategy策略模式
- 设计模式(12) - Template模板方法模式
- Android_ViewPager_实现多个图片水平滚动
- 设计模式(11) - Proxy代理模式
- 设计模式(10) - Facade外观模式
- 数据库事务
- HTML DOM Style 对象介绍
- 设计模式(9) - Flyweight享元模式
- 设计模式(8) - Composite组合模式
- 十五章
- 设计模式(7) - Decorator装饰者模式
- 设计模式(6) - Adapter适配器模式
- The 5 Best Things You Can Say in a Job Interview
- 一致性哈希算法以及其PHP实现
- 做爱做的事,做有快感的事
- RCU
- CentOS中安装gcc编译器
- 【内存管理】:self.变量 和 变量 的区别