Design Pattern | Observer Pattern
by Botao Xiao
在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。 观察者模式又被称为订阅-发布模式。 我认为是一个动态的模式,解决了对象之间的一对多依赖关系。
实现流程
- 实现一个被观察者接口(被订阅者接口),一般会包含一个数据结构用于存储所有的观察者引用。
public interface Observable { public void registerObserver(Observer observer); //注册观察者 public void deleteObserver(Observer observer); //删除观察者 public void notifyObserver(String message); //被观察者通知观察者更新 }
- 被观察者的实现
public class WeChatServer implements Observable { List<Observer> registeredUser = new ArrayList<Observer>(); //通过一个数据结构存储所有的观察者。 @Override public void registerObserver(Observer observer) { registeredUser.add(observer); } @Override public void deleteObserver(Observer observer) { registeredUser.remove(observer); } @Override public void notifyObserver(String message) { for(Observer observer:registeredUser){ //通过对观察者的遍历,对每个观察者进行更新。 observer.update(message); } } public static void main(String[] args) { Observable observable = new WeChatServer(); User1 user1 = new User1(); User2 user2 = new User2(); observable.registerObserver(user1); observable.registerObserver(user2); observable.notifyObserver("Hello It's me!"); user1.loadMessage(); user2.loadMessage(); observable.deleteObserver(user2); observable.notifyObserver("Hello again!"); user1.loadMessage(); user2.loadMessage(); } } Hello It's me! Hello It's me! Hello again! //user2没有被更新,因为已经解除了注册 Hello It's me!
- 被观察者的实现
- 实现一个观察者接口(订阅者接口),定义了当被观察者更新后,观察者对应的行为。
public interface Observer { public void update(String s); //观察者内部的更新,在通知中被调用 }
- 观察者的实现
public class User1 implements Observer { private String message; @Override public void update(String s) { this.message = s; } public void loadMessage(){ System.out.println(this.message); } } public class User2 implements Observer { //实际上没有必要实现多个观察者 private String message; @Override public void update(String s) { this.message = s; } public void loadMessage(){ System.out.println(this.message); } }
- 观察者的实现
总结
- 这个模式是松偶合的。改变主题或观察者中的一方,另一方不会受到影像。
- JDK中也有自带的观察者模式。但是被观察者是一个类而不是接口,限制了它的复用能力。但是这个类是线程安全的,但是效率很低,通过Vector实现,一次锁定整个数据结构。
Reference
Subscribe via RSS