设计模式之观察者模式(二) Java内置实现理解和使用

观察者模式(Observable实体类 Observer接口)Java内置实现理解和使用

Java内置的观察者模式,是通过继承父类,实现观察者模式的几个主要函数

Observable(可被观察的):是一个父类(class),内部已经实现了注册观察者:addObservar(),删除观察者:deleteObserver()等方法,通知观察者:notifyObservers();setChanged()用来标记主题的状态(可观察者),如果状态改变,将通知观察者

 

Oberver(观察者):是一个inferface(接口),实现update()方法,更改观察者数据,业务实现可在update()方法中去实现

主题(可观察者):主要流程  setChanged->notifyObservers(),要先调用setChanged()方法,再使用notifyObservers()方法,可以理解为先确认再提交,其实也是调用setChanged方法,主要是用来标记可观察者状态,下一步进行通知观察者。

观察者:更新接口update(Observerable obs,Object args)方法,即可以使用推(push)或者拉(pull)方式,拉的方式即使用get方法来获取。

 

观察者的通知(notify)顺序是先入后出的模式

可观察者到观察者的主要流转是这个样子的:可观察者调用setChanged()方法,来进行标记状态,表明主题发生改变,然后调用notifyObservers()方法,调用这个方法后,因为观察者实现了Observer接口,有update(Observerable obs,Object args)方法,会直接调用update(Observableobs,Object args)方法,就是说在update方法中,进行实现业务的过程中,先判断arg是否为null,来进行业务实现,如果args为null,则采用pull方式,如果不为null,则采用push的方式,获取数据就可以进行业务实现,不同的观察者可以订阅同一个可观察者(个人理解,可能会有偏差,如果疑问,可以进行评论,再次进行改进

下面代码展示一下,看下效果:

/**
 * Created on 2019/3/31.
 * Title: Simple
 * Description:可观察者
 * Copyright: Copyright(c) 2019
 * 
 *
 * @author wy
 */
public class CityObservable extends Observable {
    private float temperature;
    private float humidity;
    private float pressure;

    public CityObservable() {}

    public void measurementsChanged() {
        setChanged();
        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;
    }
/**
 * Created on 2019/3/31.
 * Title: Simple
 * Description:观察者(并进行一些项目描述,应该如何去实现业务)
 * Copyright: Copyright(c) 2019
 * Company:
 *
 * @author wy
 */
public class CurrentConditionsDisplay implements Observer ,DisplayInterface {
    Observable observable;
    private float temperature;
    private float humidity;

    public CurrentConditionsDisplay(Observable observable) {
        this.observable = observable;
        observable.addObserver(this);
    }

    @Override
    public void display() {
        // TODO Auto-generated method stub
        System.out.println("Current conditions: " + temperature +
                "F degrees and " + humidity + "% humidity");
    }

    @Override
    public void update(Observable o, Object arg) {
        // TODO Auto-generated method stub
        if (o instanceof CityObservable) {
            //TODO  可以进行业务实现
            if (null==arg){
                CityObservable weatherData = (CityObservable) o;
                this.temperature = weatherData.getTemperature();
                this.humidity = weatherData.getHumidity();
                display();
            }else {
                //TODO 声明
                //采用推的方式,直接获取参数即可,如果知道可观察者的通知方法,就可以知道采用什么方式,
                //在此,因为我们知道可观察者的调用方法,所以直接可以采用pull的方式来获取
            }

        }
    }
/**
 * Created on 2019/3/31.
 * Title: Simple
 * Description:观察者
 * Copyright: Copyright(c) 2019
 * 
 *
 * @author wy
 */
public class ForecastDisplay implements Observer,DisplayInterface{
    Observable observable;
    private float temperature;
    private float humidity;

    public ForecastDisplay(Observable observable) {
        this.observable = observable;
        observable.addObserver(this);
    }

    @Override
    public void display() {
        // TODO Auto-generated method stub
        System.out.println("ForecastDisplay: " + temperature +
                "F degrees and " + humidity + "% humidity");
    }

    @Override
    public void update(Observable o, Object arg) {
        // TODO Auto-generated method stub
        if (o instanceof CityObservable) {
            CityObservable weatherData = (CityObservable) o;
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
            display();
        }
    }
/**
 * Created on 2019/3/31.
 * Title: Simple
 * Description:接口
 * Copyright: Copyright(c) 2019
 * 
 *
 * @author wy
 */
public interface DisplayInterface {
    public void display();
}
/**
 * Created on 2019/3/31.
 * Title: Simple
 * Description:测试类
 * Copyright: Copyright(c) 2019
 *
 * @author wy
 */
public class Test {
    public static void main(String[] args) {
        CityObservable cityObservable = new CityObservable();
        CurrentConditionsDisplay currentConditions = new CurrentConditionsDisplay(cityObservable);
        StatisticsDisplay statisticsDisplay = new StatisticsDisplay(cityObservable);
        
        cityObservable.setMeasurements(82, 70, 29.2f);
        cityObservable.setMeasurements(78, 90, 29.2f);
    }
}

由结果可见先进后出

我们在项目开发时不能依赖于被通知的次序:

Java.util.Observable实现了它的notifyObservers()方法,这导致了通知观察者的次序就不是有序的顺序,但是由上例所示,如果我们依赖于观察者获取数据的顺序就是错误的。

因为一旦观察者或者可观察者的实现有所改变,通知的次序可能就会改变,很可能会产生错误的结果,所以说在项目实现时不能依赖于观察者获取数据的顺序来进行实现,这绝对不是我们所认为的松耦合。(有些是个人理解的成分在内,如果不同的理解,可以评论,大家共同进步)

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值