2观察者模式

Posted use-d

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2观察者模式相关的知识,希望对你有一定的参考价值。

观察者模式定义:定义了对象之间一对多的依赖,这样一来,当一个对象状态发生变化时,它所有的依赖者都会收到通知并自动更新。
个人理解:主题发生变化时,把变化情况及时通知到订阅了主题的各个观察者(订阅者)
观察者模式设计方式让主题 与 观察者 之间实现了松耦合,能够适应变化。
 
  • 观察者模式定义了对象之间一对多的关系
  • 主题使用一个共同接口来更新观察者
  • 主题与观察者之间用松耦合方式结合
  • 主题可以被观察者模式用push或者pull数据
  • 有多个观察者时不能依赖特定的通知顺序
  • Java有多种观察者模式,例如通用的java.util.Observable
  • Swing大量使用观察者模式
  • 此模式也被使用在JavaBeans、RMI应用中。
  定义主题接口,提供主题必须实现三个方法:注册、删除、通知

public
interface Subject { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); }

 

实现具体的天气主题:
实现Subject接口,实现注册、删除、通知方法;
定义观察者集合用于观察者注册时使用;
定义更新天气数据setMeasurements方法,该方法内默认调用measurementsChanaged方法(调用notifyObservers,循环观察者集合,调用每个观察者的update更新方法)
public class WeatherDataSubject implements Subject{
    List<Observer> observers;
    private float temp;
    private float humidity;
    private float pressure;

    public WeatherDataSubject() {
        observers = new ArrayList<>();
    }

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

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for(Observer observer:observers) {
            observer.update(temp, humidity , pressure);
        }
    }

    public void measurementsChanaged() {
        notifyObservers();
    }

    public void setMeasurements(float temp, float humidity , float pressure) {
        this.temp = temp;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanaged();
    }
}

 

定义观察者接口:
每个观察者必须实现的update方法,用于被主题调用,实现通知功能
public interface Observer {
    void update(float temp,float humidity ,float pressure);
}

 

定义观察者显示方法:
public interface DisplayElement {
    void display();
}

 

以下三个观察者实现了Observer接口、DisplayElement 显示接口:
在update方法中,默认调用display显示方法;
在具体的观察者中定义了个性化的显示方式;
public class CurrentConditionsDisplay implements Observer,DisplayElement {
    private float temp;
    private float humidity;
    private float pressure;

    @Override
    public void display() {
        System.out.println("CurrentConditionsDisplay:temp="+temp+";humidity="+humidity+";pressure="+pressure);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temp = temp;
        this.humidity = humidity;
        this.pressure = pressure;
        display();
    }
}
public class StatisticsDisplay implements Observer,DisplayElement {
    private float temp;
    private float humidity;
    private float pressure;
    
    @Override
    public void display() {
        System.out.println("StatisticsDisplay:temp="+temp+";humidity="+humidity+";pressure="+pressure);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temp = temp;
        this.humidity = humidity;
        this.pressure = pressure;
        display();
    }
}
public class ThirdPartyDisplay implements Observer,DisplayElement {
    private float temp;
    private float humidity;
    private float pressure;

    @Override
    public void display() {
        System.out.println("ThirdPartyDisplay:temp="+temp+";humidity="+humidity+";pressure="+pressure);
    }

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

 

测试类:
public class Test {
    public static void main(String[] args) {
        //观察者
        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay();
        StatisticsDisplay statisticsDisplay = new StatisticsDisplay();
        ThirdPartyDisplay thirdPartyDisplay = new ThirdPartyDisplay();
        //主题
        WeatherDataSubject subject = new WeatherDataSubject();
        //把观察者注册到主题中
        subject.registerObserver(currentConditionsDisplay);
        subject.registerObserver(statisticsDisplay);
        subject.registerObserver(thirdPartyDisplay);

        subject.setMeasurements(1,1,1);
        subject.setMeasurements(2,3,4);
    }
}

输出结果:

CurrentConditionsDisplay:temp=1.0;humidity=1.0;pressure=1.0
StatisticsDisplay:temp=1.0;humidity=1.0;pressure=1.0
ThirdPartyDisplay:temp=1.0;humidity=1.0;pressure=1.0


CurrentConditionsDisplay:temp=2.0;humidity=3.0;pressure=4.0
StatisticsDisplay:temp=2.0;humidity=3.0;pressure=4.0
ThirdPartyDisplay:temp=2.0;humidity=3.0;pressure=4.0







以上是关于2观察者模式的主要内容,如果未能解决你的问题,请参考以下文章

未调用 LiveData 观察者

Java设计模式补充:回调模式事件监听器模式观察者模式(转)

设计模式观察者模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

设计模式之观察者模式2

设计模式 -- 观察者模式

PHP设计模式之----观察者模式