zoukankan      html  css  js  c++  java
  • 观察者模式

    观察者模式

    观察者模式定义了一系列对象之间的一对多关系。

    当一个对象改变状态其他依赖者都会收到通知。

    一对多:
    利用观察者模式,主题是具有状态的对象,并且可以控制状态。也就是说,有“一个”
    具有状态的主题。另一方面,观察者使用这些状态,虽然这些状态并不属于它们。有
    许多的观察者,依赖主题来告诉她们状态何时改变了。这就产生一个关系:“一个”主题对
    “多个”观察者的关系。

    松耦合:
    改变主题或观察者其中一方,并不会影响另一方。

    松耦合的设计之所以能让我们建立富有弹性的OO系统,能够应付变化,是因为对象之间的互相
    依赖降低到了最低。

    要点:
    1、观察者模式定义了对象之间一对多的关系。
    2、主题(也就是可观察者)用一个共同的接口来更新观察者
    3、观察者和可观察者之间用松耦合方式结合(loosecoupling),可观察者不知道观察者的细节,只知道观察者实现了观察者接口。
    4、使用此模式时,你可以从被观察者处推(push)或者拉(pull)数据(然而,推的方式被认为更“正确”)。
    5、使用此模式时,不可以依赖特定的通知次序。
    6、Swing大量使用观察者模式,许多GUI框架也是如此。
    7、此模式也被应用在许多地方。例如:JavaBeans、RMI
    8、Java有多种观察者模式的实现,包括了通用的java.util.Observable
    要注意java.util.Observable实现上所带来的一些问题。如果有必要的话,可以实现自己的Observable,这并不难,Donot afraid

    --------------------------------------------------
    Swing使用观察者模式:

    //观察者,实现接口
    public class TestListener implements ActionListener{
      public void actionPerformed(ActionEvent event)
      {
        //...
      }
    }

    //被观察者
    JButton btn = new JButton("test");
    //相当于注册过程
    btn.addActionListener(new TestListener());
    --------------------------------------------------
    java内置的观察者模式Observer接口与Observable不再详述
    --------------------------------------------------

    观察者模式伪代码:

    被观察者:气象站
    观察者:3个布告板,目前状况布告板,统计布告板,预测布告板

    实现气象站:

    首先,为了松耦合,建立接口。

    主题接口:
    public interface Subject{
      public void registerObserver(Observer o);//注册观察者
      public void removeObserver(Observer o);//删除观察者
      public void notifyObservers();//当主题状态改变时,这个方法会被调用,以通知所有的观察者
    }


    public interface Observer{
      //观察者接口函数,主题状态改变时,调用此函数
      public void update(float temp, float humidity, float pressure);
    }

    public interface DisplayElement{
      public void display();//当布告板需要显示时,调用此方法。
    }

    在WeatherData中实现主题接口
    public class WeatherData implements Subject {
      private ArrayList observers;//记录观察者
      private temperature;
      private humidity;
      private pressure;

      public WeatherData()
      {
        observers = new ArrayList();
      }

      public void registerObserver(Observer o)
      {
        observers.add(o);
      }

      public void removeObserver(Observer o)
      {
        int i = observers.indeOf(o);
        if(i >= 0)
        {
          observers.remove(i);
        }
      }

      public void notifyObservers()
      {
        for(int i=0;i <observers.size();i++)
        {
          Observer ob = (Observer)observers.get(i);
          observers.update(temperature, humidity, pressure);//通知观察者
        }
      }

      public void changeData(float temp, float humidity, float pressure)
      {
        this.temp = temp;
        this.humidity = humidity;
        this.pressure = pressure;

        notifyObservers();//通知观察者
      }

    }

    实现布告板:
    目前状况布告板
    public class CurrentConditionsDisplay implements Observer, DisplayElement()
    {
      private float temperature;
      private float humidity;
      private Subjuct weatherData;

      public CurrentConditionsDisplay(Subjuct weatherData)
      {
        this.weatherData = weatherData;

        weatherData.registerObserver(this);//注册观察者
      }

      public void update(float temp, float humidity, float pressure)
      {
        this.temperature = temp;
        this.humidity = humidity;
        display();
      }

      public void display()
      {
        //...
      }

    }

    统计布告板
    public class StatisticsDisplay implements Observer, DisplayElement()
    {
      private float temperature;
      private float humidity;
      private float pressure;
      private Subjuct weatherData;

      public StatisticsDisplay(Subjuct weatherData)
      {
        this.weatherData = weatherData;

        weatherData.registerObserver(this);//注册观察者
      }

      public void update(float temp, float humidity, float pressure)
      {
        this.temperature = temp;
        this.humidity = humidity;
        this.pressure = pressure;
        display();
      }

      public void display()
      {
        //...
      }

    }

    建立测试程序,启动气象站。

    public class WeatherStation{
      public static void main(String[] args)
      {
        Subject weatherData = new WeatherData();
        CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
        StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);

        weatherData.changeData(88, 70, 30.3f);
      }
    }

  • 相关阅读:
    java面向对象3
    java面向对象2
    java面向对象1
    java基础5
    java基础4
    java基础3
    递归之汉诺塔问题
    自定义 strcpy函数
    自定义strcmp函数
    自定义strcat函数
  • 原文地址:https://www.cnblogs.com/zhangxuan/p/8336013.html
Copyright © 2011-2022 走看看