zoukankan      html  css  js  c++  java
  • Java API 设计模式之观察者(Observer)

         这是一个行为型设计模式,是MVC体系结构的基础。    

         Java API 包含了运用观察器设计模式的类。类java.util.Observable代表一个主题。类Observable提供了方法addObserver,该方法带有一个java.util.Observer参数。接口Observer允许Observable对象在其发生状态改变时向Observer发出通知。这个Observer可以是任何一个实现接口Observer的类的实例。因为Observable对象调用在接口Observer中定义的方法,这些对象仍然保持松散耦合关系。如果开发人员改变了一个具体Observer响应Observable对象状态发生改变时的方式,他不必改变这个Observable对象。Observable对象仅仅通过接口Observer与它的Observer进行交互,这保证了松散耦合。

         Swing GUI 组件运用了观察者设计模式。GUI组件与它们的监听器进行协作,以响应用户交互。比如,一个ActionListener通过注册处理一个JButton(主题)的事件而观察JButton的状态变化。当按钮被用户按下后,这个JButton通知它的ActionListener对象(观察器),它的状态已经发生改变。

         假定我们希望设计一个用来查看银行账户信息的程序。此系统包括类BankStatementData(它存储银行结单的数据)以及用来显示这些数据的类TextDisplay,BarGrahpDisplay和PieChartDisplay。分别以文本,柱状图,饼图来显示数据。我们希望设计的系统是这样的,BankStatementData对象可以通知那些显示数组的对象,并且希望主题类与观察者类之间是松散耦合的。

         观察者设计模式提倡一个主题对象和观察者对象之间的松散耦合----当主题对象发生改变的时候,它通知观察器。当得到主题对象的通知时,观察器对象发生改变以响应主题对象的状态变化。在上面的例子中,BankStatementData对象是主题对象,显示数据的三个对象是观察器。一个主题对象可以通知若干个观察器。因此主题对象与观察器之间具有一对多的关系。

    意图:

         在对象之间定义一个一对多的依赖。当一个对象发生变化的时候,它会通知所有依赖它的对象,并且这些依赖它的对象自动更新。

    动机:

         这个模式中两个关键的对象是主题和观察者。一个主题可能有很多依赖它的观察者。当主题的状态发生变化时,必须通知所有的依赖它的观察者。所为回应,每个观察者都会通知主题以同步自己与主题的状态。

    实现:

         一个定义观察者接口的抽象类:

    class Subject;

    class Observer {

    public:

         virtual ~Observer();

         virtual void Update(Subject * theChangedSubject) = 0;

    protected:

         Observer();

    };

         一个定义主题接口的抽象类:

    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(){   //当this发生变化时,它会通知所有依赖它的观察者

         ListIterator<Observer*> i(_observers);

         for(i.First(); !i.IsDone(); i.Next()){

              i.CurrentItem()->Update(this);

         }

    };

    一个具体的Subject类:

    class ClockTimer : public Subject {

    public:

         ClockTimer();

        

         virtual int GetHour();

         virtual int GetMinute();

         virtual int GetSecond();

         void Tick();   // updates the ClockTimer's internal state and calls Notify to inform observers of the change.

    };

    void ClockTimer::Tick() {

         //update internal time-keeping state

         //...

         Notify();

    }

    class DigitalClock : public Widget, public Observer {

    public:

         DigitalClock(ClockTimer*);

         virtual ~DigitalClock();

         virutal void Update(Subject*); //overrides Observer operation

         virtual void Draw(); // overrides Widgets Operation, defines how to draw the digital clock

    private:

         ClockTimer *_subject;   //具体Observer类持有一个具体Subject类的对象

    };

    DigitalClock::DigitalClock(ClockTimer *s) {

         _subject = s;

         _subject->Attach(this);

    }

    DigitalClock::DigitalClock(ClockTimer *s) {

         _subject->Detach(this);

    }

    void DigitalClock::Update(Subject * theChangedSubject) {

         if(theChangedSubject == _subject){

              Draw();

         }

    }

    void DigitalClock::Draw() {

         //draw the digital clock

    }

    另一个Observer具体类的定义

    class AnalogClock : public Widget, public Observer {

    public:

         AnalogClock(ClockTimer *) ;  //用一个具体主题类的对象来构造具体观察者类

         virtual void Update(Subject*);

         virtual void Draw();

    private:

         ClockTimer * _subject;

    };

    主函数中的代码:

    创建两个不同的Observer具体类对象和一个Subject具体类对象。用来显示一致的时间。

    ClockTimer * timer = new ClockTimer();

    AnalogClock * analogClock = new AnalogClock(timer);

    DigitalClock* digitalClock = new DigitalClock(timer);

    这样, 当timer变化时,它的值会在analogClock和digitalClock上显示出来。

  • 相关阅读:
    数字化工厂仿真系统-易景空间数字孪生工厂
    会议小程序-智能会议助手在会务系统中的优势
    商场室内地图制作-商场导航-智慧商业综合体
    室内定位室内导航到底能带来什么?
    医院导航系统-智慧医院室内导航-院内导航系统
    室内地图制作-首款实时室内绘制室内地图-3D室内地图
    城市综合三维管网管理-城市三维GIS管线系统-易景地图三维管线地图制作平台
    如何制作好看的室内地图-室内电子地图-在线制作室内地图
    jQuery ui中sortable draggable droppable的使用
    综合CSS3 transition、transform、animation写的一个动画导航
  • 原文地址:https://www.cnblogs.com/afreethinker/p/3274563.html
Copyright © 2011-2022 走看看