概述
观察者模式是一种使用率极高的模式,用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应。在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间可以没有任何相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展。
观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
案例
前言:观察者模式有两种方模型,分别是 推模型和 拉模型
推模型: 主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。该模式下如果推送数据变了观察者都得改
拉模型: 主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于是观察者从主题对象中拉数据。一般这种 模型的实现中,会把主题对象自身通过update()方法传递给观察者,这样在观察者需要获取数据的时候,就可以通过这个引用来获取了。
UML结构图
抽象主题(Subject)角色: 将观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供接口,可以增加和删除观察者对象。抽象主题角色又叫做抽象被观察者(Observable)角色。
具体主题(ConcreteSubject)角色: 将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。
抽象观察者(Observer)角色: 为所有的具体观察者定义一个更新接口,在得到主题的通知时更新自己。
具体观察者(ConcreteObserver)角色: 观察者的具体实现对象,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。
推模式
1.定义目标对象,它知道观察它的观察者,并提供注册和删除观察者的接口
public class Subject {
//用来保存观察者对象
private List<Observer> observerList = new ArrayList<>();
//将注册的对象保存到list数组中
public void register(Observer observer){
observerList.add(observer);
}
//通知观察对象
public void notifyObserver(String state){
for (Observer observer :observerList){
observer.update(state);
}
}
}
2.具体的目标对象,负责把有关状态存入到相应的观察者对象,并在自己状态发生改变时,通知各个观察者
public class ConcreteObject extends Subject {
private String state;
public String getState() {
return state;
}
public void changeState(String state){
this.state=state;
this.notifyObserver(state);
}
}
3.创建观察者接口,定义一个更新的接口给那些在目标发生改变的时候被通知的对象
public interface Observer {
public void update(String state);
}
4.具体观察者对象,实现更新的方法,使自身的状态和目标的状态保持一致
public class ConcreteObserver implements Observer {
@Override
public void update(String state) {
System.out.println("接收到状态变更为"+state);
}
}
5.创建推模型客户端,用于测试
Observer observer = new ConcreteObserver();
ConcreteObject object = new ConcreteObject();
object.register(observer);
object.notifyObserver("3");
拉模式
拉模式其实将自身传递给观察者,让观察者自己去按需要取值。也就是update方法传的是观察对象。
JDK中的应用
在JAVA语言的 java.util 库里面,提供了一个 Observable类以及一个 Observer接口,构成JAVA语言对观察者模式的支持。
示例:
1.定义两个实现了 实现java.util.Observer接口的观察者
public class SubscribeReader implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("读取信息" + ((Publish) o).getMessage());
}
}
public class SubscribeWrite implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("写入信息" + ((Publish) o).getMessage());
}
}
2.创建继承 java.util.Observable的通知者
public class Publish extends Observable {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
super.setChanged();
super.notifyObservers();
}
}
3.创建测试客户端
Observer observerReader = new SubscribeReader();
Observer observerWriter = new SubscribeWrite();
Publish publish = new Publish();
publish.addObserver(observerReader);
publish.addObserver(observerWriter);
publish.setMessage("Hello Kevin");
publish.setMessage("QQ:173xxxxxx15");
publish.setMessage("Email:173xxxxxx15@163.com");
原文:https://www.cnblogs.com/bape/p/9055306.html