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上显示出来。

  • 相关阅读:
    博客迁移至wordpress--http://i1994898w1.imwork.net/wordpress
    超外差接收机的中频选择
    The Basics of the Doherty Amplifier-Bill Slade [转载]
    闻灾情 忆国殇 山河呜咽 寄哀思
    Simplest Doppler Radar System
    开发人员的奋斗目标
    敏捷开发的推理
    在创业型软件公司的收获
    人才市场的IT职位分析
    MySQL 基础及性能优化工具
  • 原文地址:https://www.cnblogs.com/afreethinker/p/3274563.html
Copyright © 2011-2022 走看看