定义:
一个对象进行某些操作时,主动通知另外一个对象。属于行为型设计模式。
场景:
例如有多个天气公告牌,公告牌展示的数据不同,格式不同,数据来源相同。
此时,数据源是主题,即被观察者, 天气公告牌是观察者。
类图如下:
notifyObservers一般 是对每一个Observer 调用update接口
这样WeatherData 和 WeatherDisplay 解耦,而且Dsiplay可以扩展。
JDK的实现
JDK中提供了观察者模式的接口,分别是Observable和Observer
Observable 是一个具体的类,直接继承就可以使用,提供了更多的方法。
方法清单:
addObserver //添加
deleteObserver //删除
notifyObservers() //通知
notifyObservers(Object args) // 带参数通知
deleteObservers // 删除所有
//对changed标志位的控制
setChanged
clearChanged
hasChanged
countObservers
部分源码
public class Observable {
private boolean changed = false;
private Vector<Observer> obs;
可以看到这个实现,比之前的例子多了标志位的控制,避免没有改变的情况下反复通知,而且可以选择通知时带什么参数,并且内部实现时,做了加锁同步,尽管Vertor是线程安全的,但是有大量的复合,遍历操作。 需要避免竞态。
很不错?缺点?
- Observable是具体的类,导致有的对象如果已经有父类,就无法继承Observable
- Vector是despertate的容器。
还有更多的缺点,直接导致JDK9中,Observable类被desperate。
见:https://docs.oracle.com/javase/9/docs/api/java/util/Observable.html
This class and the
Observer
interface have been deprecated. The event model supported byObserver
andObservable
is quite limited, the order of notifications delivered byObservable
is unspecified, and state changes are not in one-for-one correspondence with notifications. For a richer event model, consider using thejava.beans
package. For reliable and ordered messaging among threads, consider using one of the concurrent data structures in thejava.util.concurrent
package. For reactive streams style programming, see theFlow
API
这里做了三个推荐
- 丰富的事件模型,java beans
- 并发数据结构,java.util.concurrent
- 响应式流式风格,考虑Flow API