JAVA语言观察者模式适用场景和手动实现
Vivian 2018-07-03 来源 : 阅读 721 评论 0

摘要:本文主要向大家介绍了JAVA语言观察者模式适用场景和手动实现,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了JAVA语言观察者模式适用场景和手动实现,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

定义:对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

一、适用场景

1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。

2.当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。

3.当一个对象必须通知其它对象, 而它又不能假定其它对象是谁。

二、涉及对象

1.主题接口(Subject):目标知道它的观察者。 可以有任意多个观察者观察同一个目标。提供注册和删除观察者对象的接口。

2.观察者接口(Observer):为那些在主题发生改变时需获得通知的对象定义一个更新接口

3.具体主题(ConcretSubject):将有关状态存入各ConcreteObserver 对象。当它的状态发生改变时,向它的各个观察者发出通知。

4.具体观察者(ConcretObserver):维护一个指向ConcreteSubject 对象的引用。存储有关状态, 这些状态应与目标的状态保持一致。实现 Observer 的更新接口使自身状态与目标的状态保持一致。

例子一:手动实现观察者模式

Subject类:

public interface Subject {            

//注册观察者    public void

   //删除观察者     public void

removeObserver(Observer o);   

//当主题状态改变时,调用该方法,通知所有的观察者 

public void notifyObservers(); }

   

Observer类:

public interface Observer {   

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

   

需求的额外接口DisplayElement:

public interface DisplayElement {

    public void display();

}

   

具体主题类–WeatherData


import java.util.ArrayList;
public class WeatherData implements Subject{
 
    private ArrayList observers;//记录观察者
 
    private float temperture;
 
    private float humidity;
 
    private float pressure;
 
    public WeatherData() {
        //在构造器中建立观察者
        observers = new ArrayList();
    }
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
 
    }
 
    @Override
    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        if(i>=0)
            observers.remove(i);
    }
 
    @Override
    public void notifyObservers() {
        for (int i = 0; i < observers.size(); i++) {
            Observer observer = (Observer) observers.get(i);
            observer.update(temperture, humidity, pressure);
        }  
    }
 
    //当气象站得到更新观测值时,通知观察者
    public void measurementsChanged(){
        notifyObservers();
    }
 
    public void setMeasurements(float temperature,float humidity,float pressure){
        this.temperture=temperature;
        this.humidity=humidity;
        this.pressure=pressure;
        measurementsChanged();
    }
}

   

具体观察者CurrentConditionDisplay:


public class CurrentConditionsDislpay
            implements Observer, DisplayElement {
 
    private float temperture;
 
    private float humidity;
 
    private Subject weatherData;
 
    public  CurrentConditionsDislpay(Subject weatherData) {
        this.weatherData=weatherData;
        weatherData.registerObserver(this);
    }
 
    @Override
    public void update(float temperture, float humidity, float pressure) {
        this.humidity=humidity;
        this.temperture=temperture;
        display();
 
    }
 
    @Override
    public void display() {
        System.out.println("Current conditions:"+temperture+"F degrees and "+humidity+"% humidity");
 
    }
 
}

   

测试类TestObserver:

   

public class TestObserver {
    public static void main(String[] args) {
        WeatherData  weatherData = new WeatherData();
        CurrentConditionsDislpay currentDisplay = new CurrentConditionsDislpay(weatherData);
        weatherData.setMeasurements(80, 65, 30.4f);
    }
}

   

例子二:使用JAVA内置的支持实现

具体主题类WeatherData:

import java.util.Observable;
 
public class WeatherData extends Observable{
 
    private float temperture;
 
    private float humidity;
 
    private float pressure;
 
    public WeatherData() {
 
    }
 
    //当气象站得到更新观测值时,通知观察者
    public void measurementsChanged(){
        setChanged();
        notifyObservers();
    }
 
    public void setMeasurements(float temperature,float humidity,float pressure){
        this.temperture=temperature;
        this.humidity=humidity;
        this.pressure=pressure;
        measurementsChanged();
    }
 
    public float getTemperture() {
        return temperture;
    }
 
    public void setTemperture(float temperture) {
        this.temperture = temperture;
    }
 
    public float getHumidity() {
        return humidity;
    }
 
    public void setHumidity(float humidity) {
        this.humidity = humidity;
    }
 
    public float getPressure() {
        return pressure;
    }
 
    public void setPressure(float pressure) {
        this.pressure = pressure;
    }
}

   

具体观察者:

import java.util.Observable;
import java.util.Observer;
 
public class CurrentConditionsDislpay implements Observer, displayElement {
 
    private float temperture;
 
    private float humidity;
 
    Observable observable;
 
    public  CurrentConditionsDislpay(Observable observable) {
        this.observable=observable;
        observable.addObserver(this);
    }
 
    @Override
    public void display() {
        System.out.println("Current conditions:"+temperture+"F degrees and "+humidity+"% humidity");
 
    }
 
    @Override
    public void update(Observable o, Object arg) {
        if(o instanceof WeatherData){
            WeatherData weatherData = (WeatherData) o;
            this.temperture=weatherData.getTemperture();
            this.humidity=weatherData.getHumidity();
            display();
        }
    }
}

   

测试类和所需要的接口DisplayElement和手动实现的相同。

三、设计原则

1.找出程序中会变化的方面,然后将其和固定不变的方面相分离。
在观察者模式中,会改变的是主题的状态,以及观察者的数目和类型。用这个模式,你可以改变依赖与主题状态的对象,却不必改变主题。这为提前规划。

2.针对接口编程,不针对实现编程
主题与观察者都使用接口,观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者,这样可以让两者之间运作正常,又同时具有松耦合的优点。

3.多组合,少继承
观察者模式利用组合将许多观察者组合进主题中,对象之间的这种关系不是通过继承产生的,而是在运行时利用组合的方式产生的。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!

本文由 @Vivian 发布于职坐标。未经许可,禁止转载。
喜欢 | 2 不喜欢 | 0
看完这篇文章有何感觉?已经有2人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程