观察者模式Observer是⼀种⾏为设计模式, 允许你定义⼀种订阅机制, 可在对象事件发⽣时通知多个 “观察” 该对象的其他对象。
观察者结构
- Subject被观察的⽬标
- Observer观察者抽象类
- 具体的观察者实现类
- Client客户端
观察者模式通常目标只有一个,但是观察者会有多个,多个观察者会对这一个目标从不同角度进行观察
案例代码:
模拟一个服务器被多个观察者监听的过程
内部持有Subject对象
// 观察者接口,有观察者来实现 public abstract class Observer { //内部持有目标类 protected Server subject; //观察者的更新方法:定义真正在运行时具体的观察者做什么事情 public abstract void update(); }
Subject⽬标:Subject内部持有观察者对象集合,在合适的时机触发事件
public class Server { //观察者集合 private List<Observer> observers = new ArrayList<Observer>(); //服务器的基础指标 private int cpu; private int memory; //当有更新时,就调用changeState,进行指标状态的变更 public void changeState(int cpu,int memory){ this.cpu = cpu; this.memory = memory; System.out.println("CPU:" + cpu + "%,内存占用:" + memory + "%"); notifyAllObservers(); } public int getCpu() { return cpu; } public int getMemory() { return memory; } //当外部传入观察者,就向观察者集合添加观察者 public void addObserver(Observer observer){ observers.add(observer); } //对当前所有目标类 持有的observer对象的update方法进行调用 public void notifyAllObservers(){ for (Observer observer : observers) { // 不同的观察者执行不同的update方法 observer.update(); } } }
CPU监听器-观察者:Observer内部持有subject⽬标
//cpu运行时监听器 public class CpuObserver extends Observer{ //在构造方法时从外部传入目标类:观察者和目标类双向绑定关系,就是在每一个Observer初始化时完成的 public CpuObserver(Server subject){ this.subject = subject; this.subject.addObserver(this); } @Override public void update() { //监听CPU运行时特性 if(subject.getCpu() >= 80){ System.out.println("警报:CPU当前" + subject.getCpu()+ "%即将满载,请速查明原因"); } } }
内存监听器-观察者
//内存运行时监听器 public class MemoryObserver extends Observer{ public MemoryObserver(Server subject){ this.subject = subject; this.subject.addObserver(this); } @Override public void update() { //监听内存运行时特性 if(subject.getMemory() >= 80){ System.out.println("警报:服务器内存已占用超过" + subject.getMemory() + "%,请速查明原因"); } } }
客户端根据需要组织observer,在调⽤changeState()⽅法时触发观察者
public class Client { public static void main(String[] args) throws InterruptedException { // 实例化目标类 Server subject = new Server(); // 增加两个观察者:将目标类传入观察者中 new CpuObserver(subject); new MemoryObserver(subject); //遍历所有观察者,并通知 while(true) { int cpu = new Random().nextInt(100); int memory = new Random().nextInt(100); subject.changeState(cpu, memory); Thread.sleep(5000); } } }
观察者模式优点:
开闭原则。 你⽆需修改发布者代码就能引⼊新的订阅者类 (如果是发布者接⼝则可轻松引⼊发布者类)。
你可以在运⾏时建⽴对象之间的联系。
观察者模式适合应⽤场景:
所有的发布订阅模式
构建事件监听机制,⽐如按下按钮触发click事件
转载请注明:西门飞冰的博客 » 设计模式—观察者模式