【设计模式】之观察者模式(Observer)
来源:互联网 发布:windows日志删除记录 编辑:程序博客网 时间:2024/04/30 00:44
观察者模式的定义是:定义一个对象之间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象会自动被通知和更新。
Define a one-to-many dependency between objects so that one object changes state, all its dependents are notified and updated automatically.
在OO软件设计中,一个很重要的原则就是降低对象间的耦合关系,并且要保证对象状态的一致性。
观察者模式中有两个角色,一个是subject,另一个observer,两者的关系就是一个subject对多个observer。当subject的状态发生变化时,需要通知observer。
他们之间的信息传递有两种方式,push和pull,push方式就是subject将变化的数据push给observer;pull方式就是subject用最少的信息告诉observer它需要更新了,obserer根据自己的数据需求来获取(get)subject的数据,
如果push和pull的关系比较复杂,可以引入一个专门负责控制变化的类--ChangeManager。因此就有了使用非常广泛的MVC模型,其实MVC模型至少用到了两个设计模式,一个就是观察者模型,而control类就是中介者模式(Mediator)。
以下代码是《Design Patterns》给出的sample:
定义了一个观察者的list,以及观察者subscribe和unsubscribe的Attach, Detach函数,还有就是发送通知的Notify函数。
这里没有把Subject定义成与java的interface等价的abstract class,因为C++支持多继承。
subject.h
#ifndef _HEADER_SUBJECT_#define _HEADER_SUBJECT_#include <list>using namespace std;class Observer;class Subject {public: virtual ~Subject(); virtual void Attach(Observer*); virtual void Detach(Observer*); virtual void Notify();protected: Subject();private: list<Observer*> _observers;};#endif // _HEADER_SUBJECT_
subject.cpp
#include "subject.h"#include "observer.h"Subject::Subject() {}void Subject::Attach(Observer* o) { _observers.push_front(o);}void Subject::Detach(Observer* o) { _observers.remove(o);}void Subject::Notify() { for (list<Observer*>::iterator it = _observers.begin(); it != _observers.end(); ++it) { (*it)->Update(this); }}Subject::~Subject() { for (list<Observer*>::iterator it = _observers.begin(); it != _observers.end(); ++it) { delete *it; }}
Observer类比较简单,不过Observer是一个纯虚类,只定义了一个所有子类必须实现的Update函数。
observer.h
#ifndef _HEADER_OBSERVER_#define _HEADER_OBSERVER_class Subject;class Observer {public: virtual ~Observer() { } virtual void Update(Subject* theChangedSubject) = 0;protected: Observer() { }};#endif // _HEADER_OBSERVER_
接下来就需要定义subject与observer的实例类了,本例使用了一个时钟类作为subject的子类。
clocktimer.h
#ifndef _HEADER_CLOCK_TIMER_#define _HEADER_CLOCK_TIMER_#include "subject.h"class ClockTimer : public Subject {public: ClockTimer(); virtual int GetHour(); virtual int GetMinute(); virtual int GetSecond(); void Tick();private: int _hour; int _minute; int _second;};#endif
clocktimer.cpp
#include "clocktimer.h"ClockTimer::ClockTimer() {}int ClockTimer::GetHour() { return _hour;}int ClockTimer::GetMinute() { return _minute;}int ClockTimer::GetSecond() { return _second;}void ClockTimer::Tick() { // update internal time-keeping state // ... _hour++; _minute++; _second++; Notify();}
然后定义observer的实例类
digitalclock.h
#ifndef _HEADER_DIGITAL_CLOCK_#define _HEADER_DIGITAL_CLOCK_#include "widget.h"#include "observer.h"class ClockTimer;class DigitalClock : public Widget, public Observer {public: DigitalClock(ClockTimer*); virtual ~DigitalClock(); virtual void Update(Subject*); virtual void Draw();private: ClockTimer* _subject;};#endif
#include "digitalclock.h"#include "clocktimer.h"#include <iostream>DigitalClock::DigitalClock(ClockTimer* s) : _subject(s) { _subject->Attach(this);}DigitalClock::~DigitalClock() { _subject->Detach(this);}void DigitalClock::Update(Subject* theChangedSubject) { if (_subject == theChangedSubject) { Draw(); }}void DigitalClock::Draw() { int hour = _subject->GetHour(); int minute = _subject->GetMinute(); std::cout << "hour: " << hour << "\n" << "minute: " << minute << std::endl;}
#include "clocktimer.h"#include "digitalclock.h"int main(int argc, char** argv) { ClockTimer* timer = new ClockTimer; DigitalClock* digitalClock = new DigitalClock(timer); timer->Tick(); timer->Tick(); timer->Tick(); return 0;}
widget.h
#ifndef _HEADER_WIDGET_#define _HEADER_WIDGET_class Widget {public: virtual ~Widget() { } virtual void Draw() = 0;protected: Widget() { }};#endif
Java中已经提供了现成的Observer接口以及Observable抽象类来实现观察者模式。
不过因为java不能够多继承,因此Observable的设计有些瑕疵,具体看参加《Head First Design Patterns》观察者模式一章。
因为Observable是个类,那么继承自其他类的子类就无法复用Observable类了。
如果把Observable定义成接口,那么每次实现subject类的时候就需要重写注册,取消注册与发送通知的代码。
这个应该算是java不支持多继承的一个弊端吧?
PS:快一年没怎么动C++,还真有点手生。。。
- 设计模式之Observer(观察者模式)
- 设计模式之Observer(观察者模式)
- 【设计模式】之观察者模式(Observer)
- 设计模式之--观察者模式(Observer)
- 设计模式之观察者(Observer)模式
- 设计模式之观察者(observer)模式
- 设计模式之观察者模式(Observer)
- 设计模式之-观察者模式(Observer)
- 设计模式之观察者模式(Observer)
- 设计模式之观察者模式(Observer)
- 设计模式之观察者模式(Observer)
- 设计模式之观察者(Observer)模式
- 设计模式之观察者模式(Observer)
- 设计模式之-观察者(Observer)模式
- 设计模式之Observer(观察者)模式
- 设计模式之观察者模式(Observer)
- 设计模式之Observer(观察者)
- 设计模式之Observer 观察者
- 南京社保缴费比例
- java 单例模式详解
- Android中有用的组件被选中和按下去的变换样式
- 获取文本框的值作为a标签的参数值:
- WSGI简介-写的很清楚
- 【设计模式】之观察者模式(Observer)
- 使得文本框只能输入数字的onKeyPress事件
- 百度地图API安卓版的GPS定位
- 数据库设计--继承模式
- Bugzilla使用
- linux下的%zu
- jquery实现的全选反选全不选等等的效果源码
- Java Socket实战之二 多线程通信 .
- Linux下重启Apache