定义
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
基本概念
观察者: 依赖于目标对象的对象。
目标对象:被依赖的对象
原生实现
观察者接口
/**
* 观察者接口
*/
public interface Observer {
void update(Subject subject);
}
Reader1
public class Reader1 implements Observer{
private String content;
@Override
public void update(Subject subject) {
this.content=((Newspaper)subject).getContent();
System.out.println("读者Reader1已接收到报纸新内容:"+this.content);
}
}
Reader2
public class Reader2 implements Observer{
private String content;
@Override
public void update(Subject subject) {
this.content=((Newspaper)subject).getContent();
System.out.println("读者Reader2已接收到报纸新内容:"+this.content);
}
}
被观察对象
import java.util.ArrayList;
import java.util.List;
/**
* 被观察对象
*/
public class Subject {
private static List<Observer> observers=new ArrayList<>();
/**
* 注册观察者
* @param observer
*/
public void register(Observer observer){
observers.add(observer);
}
/**
* 删除
*/
public void delete(Observer observer){
observers.remove(observer);
}
/**
* 通知
*/
public void notifyAllObserver(){
if (!observers.isEmpty()){
observers.forEach(observer -> {
observer.update(this);
});
}
}
}
报纸
/**
* 报纸
*/
public class Newspaper extends Subject{
//报纸内容
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
//报纸内容发生变化,通知所有读者(观察者)
this.notifyAllObserver();
}
}
原生实现测试
@Test
void observerTest(){
Reader1 reader1 = new Reader1();
Reader2 reader2 = new Reader2();
Newspaper newspaper = new Newspaper();
newspaper.register(reader1);
newspaper.register(reader2);
newspaper.setContent("新内容20220813");
}
Java具有观察者模式的接口,直接实现如下:
被观察目标
import java.util.Observable;
/**
* 报纸
*/
public class JavaNewspaper extends Observable {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
//标识状态发生改变--未调用则观察者模式不生效
this.setChanged();
//无参构造
this.notifyObservers();
//传递属性----参数就是内容
//this.notifyObservers(content);
}
}
import java.util.Observable;
import java.util.Observer;
public class JavaReader1 implements Observer {
private String content;
/**
* 同时支持推拉模型
* @param o the observable object.
* @param arg an argument passed to the <code>notifyObservers</code>
* method.
*/
@Override
public void update(Observable o, Object arg) {
this.content= (String) arg;
System.out.println("JavaReader1接收到--推送的内容:"+this.content);
String content1 = ((JavaNewspaper) o).getContent();
System.out.println("JavaReader1接收到--拉取的内容:"+content1);
}
}
import java.util.Observable;
import java.util.Observer;
public class JavaReader2 implements Observer {
private String content;
/**
* 同时支持推拉模型
* @param o the observable object.
* @param arg an argument passed to the <code>notifyObservers</code>
* method.
*/
@Override
public void update(Observable o, Object arg) {
this.content= (String) arg;
System.out.println("JavaReader2接收到--推送的内容:"+this.content);
String content1 = ((JavaNewspaper) o).getContent();
System.out.println("JavaReader2接收到--拉取的内容:"+content1);
}
}
java观察者测试
@Test
void javaobserverTest(){
JavaReader1 reader1 = new JavaReader1();
JavaReader2 reader2 = new JavaReader2();
JavaNewspaper newspaper = new JavaNewspaper();
newspaper.addObserver(reader1);
newspaper.addObserver(reader2);
newspaper.setContent("新内容20220813");
}
总结
1.观察者与目标是单向依赖的,只有观察者依赖于目标
2.观察者模式就是发布订阅模式或者广播模式
3.对于java观察者实现细节:
3.1 this.setChanged(); //标识状态发生改变--未调用则观察者模式不生效
3.2 this.notifyObservers() 相当于 this.notifyObservers(null)
3.3 this.notifyObservers(arg)的参数就是Observer实现update参数中的 arg
@Override
public void update(Observable o, Object arg)
4.观察者本质:触发联动操作