观察者模式(发布-订阅模式、模型-视图模式),属于对象行为方式:
解决场景:
当一个对象改变的时候,所有依赖它的对象都需要得到通知并且针对其改变而改变。
优缺点:
目标与观察者之间抽象耦合,使用了触发机制
但是依赖仍然有,如果目标的观察者(对象依赖)很多会影响效率
需要的对象:
目标:会发生改变的对象
观察者:依赖目标的对象
事件:发生的改变的抽象类
事件 - 观察者
目标 - 事件
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); } }