观察者模式

 出版社+订阅者=观察者模式

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

我们来看一下观察者模式的类图:


其中的依赖是如何产生的:因为主题是真正拥有数据的人,观察者是主题的依赖者,在数据变化的时候更新,这样比起让许多对象控制同一份数据来,可以得到更干净的oo设计。


松耦合的威力

当两个对象之间松耦合,它们依然可以交互,但是不太清楚彼此的细节。

观察者模式提供了一种对象设计,让主题和观察者之间松耦合。

关于观察者的一切,主题只知道观察者实现了某个接口(也就是Observer接口)。主题不需要知道观察者的具体类是谁,做了些什么或其他任何细节。

我们可以独立地服用主题或观察者。如果我们在其他地方需要使用主题或观察者,可以轻易地复用,因为二者并非紧耦合。只要他们之间的接口仍被遵守,我们就可以自由的改变他们。


设计原则,为了交互对象之间的松耦合设计而努力。


我们来看看气象台实现的类图


我们目前实现的观察者模式只有主体的push机制,不能由观察者自由的去拉自己想要的数据。java的api有内置的观察者模式。两种方式都是实现了。也就是java.util包内包含的最基本的Observer接口与Observable类。




如何把对象变成观察者

实现观察者接口(java.util.Observer),然后调用任何Observable对象的addObserver()方法,退出观察者时调用deleteObserver()方法即可。

被观察者如何送出通知

1,先调用setchanged()方法,标记状态已经改变的事实。setchanged可以通过其中的标示来控制下数据刷新的灵敏度。

2,然后调用两种notifyObservers()方法中的一个,分别是notifyObservers()和notifyObservers(Object arg)。

观察者如何接收通知

更新方法update(Observable o, Object arg);


新的实现的代码

public class WeatherData extends Observable {//直接继承了Java提供的主题超类,注意这里Observable是一个类 
    private float temperature; 
    private float humidity; 
    private float pressure; 
    public WeatherData() { }//由于采用内置的主题,这里就不需要你手动维护一个观察者列表了。 
    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; 
    } 
}
我们现在再创建一个使用Java内置观察者模式完成的气象发布版:
public class CurrentConditionsDisplay implements Observer , DisplayElement {//注意这里Observer是一个接口 
    Observable observable;//主题的引用,用于注册、注销等操作 
    private float temperature; 
    private float humidity; 
    public CurrentConditionsDisplay(Observable observable) { 
        this.observable = observable; 
        observable.addObserver(this);//这里进行了注册,也可以使用
    } 
    public void update(Observable obs, Object arg) { 
        if (obs instanceof WeatherData) {//判断是不是属于WeatherData类 
            WeatherData weatherData = (WeatherData)obs; 
            this.temperature = weatherData.getTemperature();//这里体现了拉的方式 
            this.humidity = weatherData.getHumidity(); 
            display(); 
        } 
    } 
    public void display() { 
        System.out.println("Current conditions: " + temperature 
            + "F degrees and " + humidity + "% humidity"); 
    } 
}




java.util.Observable的黑暗面

1,Observable是一个类。不能双继承。

2,Observable将关键方法包含起来了。

setChanged()方法是protected。除非你继承于Observable,否则你无法创建Observale实例并组合到你自己的对象中来。这个设计违反了“多用组合,少用继承”。






一个新的模式,以松耦合方式在一系列对象之间沟通状态。观察者模式的代表人物---MVC。

要点:

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

2,主题(也就是可观察者)用一个共同的接口来更新可观察者。

3,观察者和可观察者之间通过松耦合方式结合。

4,使用此模式时,你可以从被观察者处推(push)或者拉(pull)数据(然而,推的方式被认为更“正确”)。

5,有多个观察者时,不可以依赖特定的通知次序。

6,Java有多种观察者模式的实现,包括了通用的java.util.Observable。

7,要注意java.util.Observable实现上所带来的一些问题。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值