行为型模式--观察者
1、意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
2、结构

3、参与者
Subect:目标。目标知道它的观察者。可以有任意多个观察者观察同一个目标;提供注册和删除观察者对象的接口;
Observer:观察者。为那些在目标发生改变时需获得通知的对象定义一个更新接口;
ConcreteSubject:具体目标。将有关状态存入各ConcreteObserver对象;当它的状态发生改变时,向它的各个观察者发出通知;
ConcreteObserver:具体观察者。维护一个指向ConcreteSubject对象的引用;存储有关状态,这些状态应与目标的状态保持一致;实现Observer的更新接口以使自身状态与目标的状态保持一致。
4、适用性
符合以下情况之一可使用观察者模式:
当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用;
当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变;
当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的;
5、代码示例
class Subject; class Observer { public: virtual ~Observer(); virtual void Update(Subject* thechangedsubject)= 0; protected: Observer(); }; // 支持一个观察者有多个目标。当观察者观察多个目标时,作为参数传递给Update操作的目标让观察者可以判定是哪一个目标发生了改变。 // 类似地,一个抽象类定义了Subject接口: class Subject { public: virtual ~Subject(); virtual void Attach(Observer*): virtual void Detach(Observer*); virtual void Notify(); protected: Subject (); private: List<Observer*>* _observers; }; void Subject::Attach (Observer* o) { _observers->Append(o); } void Subject::Detach (Observer* o) { _observers->Remove (o); } void Subject::Notify () { ListIterator<Observer*> i(_observers); for (i.First(); !i.IsDone(); i.Next ()) { i.CurrentItem()->Update(this); } }
// ClockTimer是一个用于存储和维护一天时间的具体目标。它每秒钟通知一次它的观察者。 // ClockTimer提供了一个接口用于取出单个的时间单位如小时,分钟,和秒。 class clockTimer : public Subject { public: clockTimer(); virtual int GetHour(); virtual int GetMinute(); virtual int GetSecond(); void Tick(); }; // Tick操作由一个内部计时器以固定的时间间隔调用,从而提供一个精确的时间基准。 // Tick更新ClockTimer的内部状态并调用Notify通知观察者: void clockTimer::Tick () { // update internal time-keeping state // ... Notify(); }
// 现在我们可以定义一个DigitalClock类来显示时间。它从一个用户界面工具箱提供的Widget类继承了它的图形功能。 // 通过继承Observer,Observer接口被融入DigitalClock的接口。 class Digitalclock : public Widget, public Observer { public: Digitalclock(ClockTimer*); virtual ~Digitalclock(); virtual void Update(Subject*); // overrides observer operation virtual void Draw(); // overrides widget operation; // defines how to draw the digital clock private: clockTimer* _subject; }; Digitalclock::Digitalclock (ClockTimer* s) { _subject = s; _subject->Attach(this); } Digitalclock::~Digitalclock () { _subject->Detach(this); } // 在Update操作画出时钟图形之前,它进行检查,以保证发出通知的目标是该时钟的目标 void Digitalclock::Update (Subject* thechangedSubject) { if (thechangedSubject == _subject) { Draw(); } } void Digitalclock::Draw () { // get the new values from the subject int hour =_subject->GetHour(); int minute =_subject->GetMinute(); // etc. // draw the digital clock }
// 一个AnalogClock可用相同的方法定义。 class Analogclock : public Widget, public observer { public: Analogclock(ClockTimer*); virtual void Update(Subject*); virtual void Draw(); // ... }; // 下面的代码创建一个AnalogClock和一个DigitalClock,它们总是显示相同时间 // 一旦timer走动,两个时钟都会被更新并正确地重新显示。 ClockTimer* timer = new ClockTimer; Analogclock* analogclock = new Analogclock(timer); Digitalclock* digitalclock = new Digitalclock(timer);
6、总结
观察者模式定义了对象间一种一对多的依赖关系,当一个对象发生改变时,所有依赖该对象的其余对象都能得到通知并做相应处理。目标发送通知,观察者接收通知。
目标与观察者之间实现了松耦合。
本文来自博客园,作者:流翎,转载请注明原文链接:https://www.cnblogs.com/hjx168/p/16221500.html

浙公网安备 33010602011771号