1.观察者模式的定义
定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
2.观察者模式实战
2.1观察者模式的结构和说明
Subject为目标,也叫被观察者,Observer为观察者。
Attach方法为添加观察者,detach方法为删除观察者,notify方法为通知观察者,执行notify时会调用观察者(Observer)的update方法更新。
ConcreteSubject为目标的具体实现类,ConcreteObserver为观察者的具体实现类。
2.2观察者模式的代码演示
统一的目标类:
具体的目标类:
统一的观察者接口:
具体的观察者:
测试类:
运行结果:
3.观察者模式详解
3.1实现的两种方式
推模型:目标对象主动向观察者推送目标的详细信息,推送的信息通常是目标对象的全部信息或者部分数据。例如:
拉模型:目标对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到目标对象中获取,相当于观察者从目标对象中拉取数据。一般这种模型的实现中,会把目标对象的自身传给update参数。例如:
两种方式的比较:
1.推模型是假定目标对象知道观察者需要的数据,拉模型是目标对象不知道观察者需要什么数据,因此把自身传给观察者,由观察者来取值。
2.推模型会使观察者对象难以复用,拉模型下,update方法的参数是目标对象的本身,基本可以适应各种情况的需要。
3.2利用jdk内置的api实现观察者模式
java.util.Observable类是目标对象,即可观察者
java.util.Observer接口是观察者接口
Jdk实现的观察者模式与自己实现的对比
1.不需要再定义观察者和目标对象的接口了,jdk帮忙定义好了;
2.具体的目标实现里面不再需要维护观察者的注册信息了,这个在java中Observable类中已经帮忙实现好了;
3.触发通知的方式有改变,要先调用setChange()方法,这个是java为了帮助更精准的触发控制而提供的功能;
4.具体的观察者类里面,update方法同时支持推模型和拉模型。
具体的目标对象类,只需要继承Observable就行了,如下:
代码解释:
使用this.notifyObservers()是使用拉模型,就是将自身传给观察者;
使用this.notifyObservers(content)是使用推模型,就是将content传给观察者;
具体的观察者类,只需要实现observer接口就行了,如下:
代码解释:
Update方法的Observable是接受目标对象的引用,即拉模型的实现;Object arg是接受目标对象传过来的内容,是推模型的实现。
测试类:
执行结果如下:
3.3观察者的优点以及何时使用观察者模式
优点:
1.观察者模式实现了观察者与目标之间的抽象耦合
2.观察者模式实现了动态联动
3.观察者模式支持广播通信
观察者模式的本质:触发联动。建议在以下情况下选用观察者模式:
1.当一个抽象模型有两个方面,其中一个方面的操作依赖于另外一个方面的状态变化;
2.如果在更改一个对象的时候,需要同时连带改变其他对象,而且不知道究竟应该有多少对象需要被连带改变;
3.当一个对象必须通知其他对象,但是又希望这个对象与其他被它通知的对象是松散耦合的。