Java 观察者模式
观察者模式的定义:在对象之间定义了一对多的依赖,当一个对象改变状态,依赖它的对象会收到通知并自动更新
比如,学校广播信息,学生获取信息,在学校的都能知道这条信息,不在学校的就不知道这条信息
该模式包含了四个角色
-
抽象被观察者角色
-
一个抽象的主题,它把所有对观察者对象的引用保存在一个集合中。
-
每个主题都可以有任意数量的观察者
-
抽象主题提供一个接口,可以 增加 和 删除 观察者角色
-
-
抽象观察者角色
-
为所有的具体观察者定义一个接口,在得到主题通知时更新自已
-
-
具体被观察者角色
-
在集体主题的内部状态改变时,给所有登记过的观察者发出通知
-
-
具体观察者角色
-
实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调
-
使用例子
定义一个抽象被观察者接口
/** * 被观察者接口 */ public interface Observerable { // 新增 一位被观察者 void addObserver(Observer observer); // 删除 一位被观察者 void removeObserver(Observer observer); // 通知 被观察者 void notifyObserver(); }
定义一个抽象观察者接口
/** * 观察者 接口 */ public interface Observer { // 当 被观察者调用 notifyObserver 时,观察者的update会回调 void update(String msg); }
定义被观察者
public class School implements Observerable { private List<Observer> list; private String msg; public School() { list = new ArrayList<>(); } @Override public void addObserver(Observer observer) { list.add(observer); } @Override public void removeObserver(Observer observer) { if (!list.isEmpty()) list.remove(observer); } @Override public void notifyObserver() { for (int i = 0; i < list.size(); i++) { Observer observer = list.get(i); observer.update(msg); } } public void setInfo(String str){ this.msg = str; System.out.println("学校通知:["+ str + "]"); // 消息更新,通知所有观察者 notifyObserver(); } } 定义具体观察者 public class XiaoMing implements Observer { private String name; private String msg; public XiaoMing(String name){ this.name = name; } @Override public void update(String msg) { this.msg = msg; read(); } public void read(){ System.out.println(name + "收到的信息:" + msg); } }
定义具体观察者
public class ZhangSan implements Observer { private String name; private String msg; public ZhangSan(String name){ this.name = name; } @Override public void update(String msg) { this.msg = msg; read(); } public void read(){ System.out.println( name + "收到的信息:" + msg); } }
测试
public class Test { public static void main(String[] args) { // 具体观察者 XiaoMing xiaoMing = new XiaoMing("小明"); ZhangSan zhangSan = new ZhangSan("张三"); // 被观察者 School school = new School(); school.addObserver(xiaoMing); school.addObserver(zhangSan); // 发布信息 school.setInfo("五一放假四天......"); System.out.println("---------------------------------"); // 假设张三听着到这个信息,很高兴,然后后面的信息就没有注意了 ( 移除观察者 ) school.removeObserver(zhangSan); // 发布信息 school.setInfo("四天后补课四天......."); } }
结果
学校通知:[五一放假四天......]
小明收到的信息:五一放假四天.....
张三收到的信息:五一放假四天.....
----------------------------
学校通知:[四天后补课四天.......]
小明收到的信息:四天后补课四天....