欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVA设计模式之观察者模式 - Observer

程序员文章站 2022-03-16 10:14:14
有趣的事情发生时,可千万别错过了!有一个模式可以帮你的对象知悉现况,不会错过该对象感兴趣的事。对象甚至在运行时可决定是否要继续被通知。有了观察者,你将会消息灵通。

有趣的事情发生时,可千万别错过了!有一个模式可以帮你的对象知悉现况,不会错过该对象感兴趣的事。对象甚至在运行时可决定是否要继续被通知。有了观察者,你将会消息灵通。

介绍

观察者模式的定义:

在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

简单理解

为了方便理解观察者模式,我们以报社为例:

  1. 报社的业务是出版报纸;
  2. 向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸。
  3. 当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸来。
  4. 只要报社还在运营,就会一直有人(或单位)

如果你了解报社的订阅是怎么回事,其实就知道观察者是怎么回事了,只是名称不太一样:
出版者改称为“主题”(subject)或“被观察者”(observable),订阅者改称为“观察者”(observer).
主题 + 观察者 = 观察者模式
主题就是定义中的“一”,观察者为定义中的“多”,当主题有变化时,便会通知它的”订阅者“也就是”观察者“

使用场景

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,a对象的行为将影响b对象,b对象的行为将影响c对象……,可以使用观察者模式创建一种链式触发机制。

举例:有一个微信公众号服务,不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。

优缺点

优点

  1. 观察者和被观察者是抽象松耦合的;
  2. 建立一套触发机制。

缺点

  1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间;
  2. 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

注意事项

  1. java 中已经有了对观察者模式的支持类;
  2. 避免循环引用;
  3. 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

实现

类图

JAVA设计模式之观察者模式 - Observer

实现步骤

创建抽象主题 - subject

public interface subject {

    //观察者订阅服务
    public void registerobserver(observer o);

    //观察者取消订阅服务
    public void removeobserver(observer o);

    //主题改变时,会被调用,通知所有观察者
    public void notifyobservers();
    
}

创建抽象观察者 - observer

public interface observer {
    
    public void update(float temp, float humidity, float pressure);
    
}

创建具体主题

public class weatherdata implements subject {
    private arraylist<observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;
    
    public weatherdata() {
        observers = new arraylist<observer>();
    }
    
    public void registerobserver(observer o) {
        observers.add(o);
    }
    
    public void removeobserver(observer o) {
        int i = observers.indexof(o);
        if (i >= 0) {
            observers.remove(i);
        }
    }
    
    public void notifyobservers() {
        for (observer observer : observers) {
            observer.update(temperature, humidity, pressure);
        }
    }
    
    public void measurementschanged() {
        notifyobservers();
    }
    
    public void setmeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementschanged();
    }

//  public float gettemperature() {
//      return temperature;
//  }
//  
//  public float gethumidity() {
//      return humidity;
//  }
//  
//  public float getpressure() {
//      return pressure;
//  }

}

创建一个具体观察者

public class currentconditionsdisplay implements observer {
    private float temperature;
    private float humidity;
    private subject weatherdata;
    
    public currentconditionsdisplay(subject weatherdata) {
        this.weatherdata = weatherdata;
        //订阅
        weatherdata.registerobserver(this);
    }
    
    public void update(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        display();
    }
    
    public void display() {
        system.out.println("current conditions: " + temperature 
            + "f degrees and " + humidity + "% humidity");
    }
}

测试

public class weatherstation {

    public static void main(string[] args) {

        //创建主题
        weatherdata weatherdata = new weatherdata();

        //创建观察者并订阅
        currentconditionsdisplay currentdisplay = new currentconditionsdisplay(weatherdata);
//      statisticsdisplay statisticsdisplay = new statisticsdisplay(weatherdata);
//      forecastdisplay forecastdisplay = new forecastdisplay(weatherdata);

        //通知观察者
        weatherdata.setmeasurements(80, 65, 30.4f);
//      weatherdata.setmeasurements(82, 70, 29.2f);
//      weatherdata.setmeasurements(78, 90, 29.2f);
    }
}

结语

设计模式源于生活