观察者模式
观察者(Observer)模式,又叫发布/订阅(Publish/Subscribe)模式。定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够更新自己。适用于当一个对象的改变需要同时改变其他对象时情形。
结构图:
Subject:主题(抽象通知者)保存多个观察者,可增加和删除观察者。
Observer:抽象观察者,得到主题(抽象通知者)的通知时更新自己,提供更新接口
ConcreteSubject:具体主题(具体通知者),具体主题内部改变时,通知所有注册过的观察者。
ConcreteObserver:具体观察者,实现更新接口,接收具体主题(具体通知者)的通知。
其中主题不知道谁是观察者,每个观察者也不知道有其他观察者的存在。
例:
public abstract class Subject { private List<Observer> list = new ArrayList<>(); // 保存观察者 public boolean add(Observer observer){ // 增加观察者 if (observer != null) { list.add(observer); return true; } return false; } public boolean remove(Observer observer){ // 移除观察者 if (observer != null) { list.remove(observer); return true; } return false; } public void notifyObservers(){ // 通知所有观察者 for (Observer observer : list) { observer.update(); } } }
public class ConcreteSubject extends Subject { private String subject_state; // 主题自身状态 public String getSubject_state() { return subject_state; } public void setSubject_state(String subject_state) { this.subject_state = subject_state; } }
public abstract class Observer { public abstract void update(); // 更新状态的接口 }
public class ConcreteObserver extends Observer{ private String name; private String observer_state; // 观察者的状态 private ConcreteSubject subject; // 观察的主题(对象) public ConcreteObserver(String name, ConcreteSubject subject) { this.name = name; this.subject = subject; } @Override public void update() { observer_state = subject.getSubject_state(); } public String getName() { return name; } public String getObserver_state() { return observer_state; } }
public class Test { public static void main(String[] args) { ConcreteSubject subject = new ConcreteSubject(); // 具体主题 ConcreteObserver observer1 = new ConcreteObserver("jzx",subject); // 观察者1 ConcreteObserver observer2 = new ConcreteObserver("zzh",subject); // 观察者2 subject.add(observer1); // 具体主题注册观察者1 subject.add(observer2); // 具体主题注册观察者2 subject.setSubject_state("发布"); // 主题改变自身状态 subject.notifyObservers(); // 主题发布通知 System.out.println(observer1.getName() + "的状态是:" + observer1.getObserver_state()); // 查看观察者1目前状态 System.out.println(observer2.getName() + "的状态是:" + observer2.getObserver_state()); // 查看观察者2目前状态 subject.remove(observer2); // 主题决定不通知observer2 subject.setSubject_state("下架"); // 主题改变自身状态 subject.notifyObservers(); // 主题发布通知 System.out.println(observer1.getName() + "的状态是:" + observer1.getObserver_state()); // 查看观察者1目前状态 System.out.println(observer2.getName() + "的状态是:" + observer2.getObserver_state()); // 查看观察者2目前状态 } }
输出:
jzx的状态是:发布
zzh的状态是:发布
jzx的状态是:下架
zzh的状态是:发布