观察者模式(发布-订阅模式、模型-视图模式),属于对象行为方式:
解决场景:
当一个对象改变的时候,所有依赖它的对象都需要得到通知并且针对其改变而改变。
优缺点:
目标与观察者之间抽象耦合,使用了触发机制
但是依赖仍然有,如果目标的观察者(对象依赖)很多会影响效率
需要的对象:
目标:会发生改变的对象
观察者:依赖目标的对象
事件:发生的改变的抽象类
事件 - 观察者
目标 - 事件
java中有具体的观察者模式类:
Observable和Observer
举例:
百变怪和武藏、小次郎
Ditto作为目标,WuZang和XiaoCiLang作为观察者(依赖)。当Ditto发生改变时,需要及时观察者及时做出改变
package com.zang.schema.observable.observer;
import java.util.Observable;
/**
* java 原生观察者模式
* Ditto 百变怪
* 目标类
* @author Zhang Qiang
* @Date 2019/8/29 17:44
*/
public class Ditto extends Observable {
private String transformation;
public String getTransformation() {
return transformation;
}
/**
* 状态改变,通知观察者
*/
public void setTransformation(String transformation) {
this.transformation = transformation;
super.setChanged();
super.notifyObservers(transformation);
}
}
观察者1:
package com.zang.schema.observable.observer;
import java.util.Observable;
import java.util.Observer;
/**
*
* @author Zhang Qiang
* @Date 2019/8/29 17:47
*/
public class WuZang implements Observer {
@Override
public void update(Observable o, Object arg) {
String res = String.valueOf(arg);
switch (res){
case "abo":
System.out.println("WuZang very like");
break;
case "fw":
System.out.println("WuZang not like");
break;
default:
System.out.println("WuZang is nothing");
break;
}
}
}
观察者2:
package com.zang.schema.observable.observer;
import java.util.Observable;
import java.util.Observer;
/**
* @author Zhang Qiang
* @Date 2019/8/29 17:51
*/
public class XiaoCiLang implements Observer {
@Override
public void update(Observable o, Object arg) {
String res = String.valueOf(arg);
switch (res){
case "abo":
System.out.println("XiaoCiLang very like");
break;
case "fw":
System.out.println("XiaoCiLang very like, and some boy");
break;
default:
System.out.println("XiaoCiLang is nothing");
break;
}
}
}
实现:
public class Action {
public static void main(String[] args) {
new Action().ditto("fw");
}
public void ditto(String dt){
Ditto ditto = new Ditto();
// 添加观察者(依赖)
ditto.addObserver(new WuZang());
ditto.addObserver(new XiaoCiLang());
// 事件发生
ditto.setTransformation(dt);
}
}