设计模式之-----观察者模式
定义:
- 定义了对象之间 一对多的依赖关系,其中被观察者是一方,观察者是多方,在被观察者发生改变时,被观察者主动调用方法,通知所有观察者的一种设计模式。
原理:
- 定义
①被观察者类,内部需要实现本身业务数据的存储,有保存所有观察者的一个数据结构类,
②观察者统一接口,定义一个统一通知方法,供被观察者数据改变后进行调用通知。
③声明观察者和被观察者对象,被观察者和观察者一对多绑定之后,被观察者数据发生改变之后,主动调用观察者的抽象接口方法进行通知。
此设计模式优缺点:
优点的话:
- 观察者与被观察者业务逻辑相互解耦
- 有一套触发机制
缺点:
- 如果被观察者的观察者对象很多的话,全部通知到会很耗时
- 观察者与被观察者直接如果存在循环依赖的话,会出现问题
- 没有具体变化详情的通知机制,观察者只是知道被观察者发生变化了
注意事项:
- 避免循环引用
- 防止观察者发生崩溃,会导致在被观察者向外通知时发生异常
其中JDK中提供了一套机制,下面依托于JDK实现一个观察者模式的demo:
- 被观察者:
java.util.Observable - 观察者对象抽象接口:
java.util.Observer - 源码分析:
其中 Observable类中的代码结构如下:
//线程同步
public class Observable {
//是否变更标识符
private boolean changed = false;
//观察者列表,继承自 AbstractList,实现了 List<E>,
//RandomAccess, Cloneable, Serializable 这些接口的列表结构
private Vector<Observer> obs = new Vector();
public Observable() {
}
//绑定观察者
public synchronized void addObserver(Observer var1) {
if (var1 == null) {
throw new NullPointerException();
} else {
//防止重复添加
if (!this.obs.contains(var1)) {
this.obs.addElement(var1);
}
}
}
//注销观察者
public synchronized void deleteObserver(Observer var1) {
this.obs.removeElement(var1);
}
//无参方式通知观察者,
public void notifyObservers() {
this.notifyObservers((Object)null);
}
//有参数式通知,实现方式:循环 可能导致的问题,一个观察者发生崩溃,程序崩溃
public void notifyObservers(Object var1) {
Object[] var2;
synchronized(this) {
if (!this.changed) {
return;
}
var2 = this.obs.toArray();
this.clearChanged();
}
for(int var3 = var2.length - 1; var3 >= 0; --var3) {
((Observer)var2[var3]).update(this, var1);
}
}
public synchronized void deleteObservers() {
this.obs.removeAllElements();
}
protected synchronized void setChanged() {
this.changed = true;
}
protected synchronized void clearChanged() {
this.changed = false;
}
public synchronized boolean hasChanged() {
return this.changed;
}
public synchronized int countObservers() {
return this.obs.size();
}
}
- 观察者抽象接口源码:
//将观察者抽象出来,
public interface Observer {
//被观察者这主动通知时,调用此方法:
void update(Observable var1, Object var2);
}
实现就很简单了,如下:
- 实现被观察者类
/**
* @author GerryRun
* @date 2020/9/21 14:52.
* @email gerryin@163.com
* @desc 被观察者
*/
public class Subject extends Observable {
private int statue;
public int getStatue() {
return statue;
}
public void setStatue(int statue) {
this.statue = statue;
//被观察者 发生改变,主动通知观察者
this.setChanged();
this.notifyObservers();
}
}
- 实现观察者类(实现Observer接口):
/**
* @author GerryRun
* @date 2020/9/21 14:55.
* @email gerryin@163.com
* @desc 观察者 一号
*/
public class OneObserver implements Observer {
public OneObserver(Observable observable) {
//与被观察者绑定
observable.addObserver(this);
}
@Override
public void update(Observable observable, Object o) {
if (observable instanceof Subject) {
System.out.println("OneObservable == " + ((Subject) observable).getStatue());
}
}
}
/**
* @author GerryRun
* @date 2020/9/21 15:02.
* @email gerryin@163.com
* @desc 观察者 二号
*/
public class TwoObserver implements Observer {
public TwoObserver(Observable observable) {
//与被观察者绑定
observable.addObserver(this);
}
@Override
public void update(Observable observable, Object o) {
if (observable instanceof Subject) {
System.out.println("TwoObserver == " + ((Subject) observable).getStatue());
//模拟通知过程中发生错误的情况
// throw new RuntimeException(" throw error message in twoObserver ");
}
}
}
- 使用:
/**
* @author GerryRun
* @date 2020/9/21 15:01.
* @email gerryin@163.com
* @desc 测试类
*/
public class TestMainClass {
public static void main(String[] args) {
Subject subject = new Subject();
new OneObserver(subject);
new TwoObserver(subject);
new OneObserver(subject);
new OneObserver(subject);
subject.setStatue(100);
}
}
- 执行main方法结果:
Task :lib_proxytest:TestMainClass.main()
OneObservable == 100
OneObservable == 100
TwoObserver == 100
OneObservable == 100
Android小白和Java小白的二十四种设计模式学习记录。