观察者模式中,一个被观察者管理所有相依于它的观察者物件,并且在本身的状态改变时主动发出通知。这通常通过
呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
角色
抽象被观察者角色:把所有对观察者对象的引用保存在一个集合中,每个被观察者角色都可以有任意数量的观察
者。被观察者提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
具体被观察者角色:在被观察者内部状态改变时,给所有登记过的观察者发出通知。具体被观察者角色通常用一个
子类实现。
具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用
一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。
开发中常见的场景
- 聊天室程序的,服务器转给所有客户端
- 网络游戏(多人联机对战)场景中,服务器将客户端的状态进行分发
- 邮件订阅
- Servlet中,监听器的实现
- Android中,广播机制
- JDK的AWT中事件处理模型,基于观察者模式的委派事件模型
- 京东商城中,群发某商品打折信息
public interface Observer { public void update(Observable o, Object arg); } public class PriceObserver implements Observer { // 实现观察者必须实现的update方法 public void update(Observable o, Object arg) { if (arg instanceof Double) { System.out.println("名称观察者: " + o + "物品价格已经改变为: " + arg); } } } public class NameObserver implements Observer { // 实现观察者必须实现的update方法 public void update(Observable o, Object arg) { if (arg instanceof String) { // 产品名称改变值在name中 String name = (String) arg; // 启动一个JFrame窗口来显示被观察者对象的状态改变 JFrame f = new JFrame("观察者"); JLabel l = new JLabel("名称改变为:" + name); f.add(l); f.pack(); f.setVisible(true); System.out.println("名称观察者: " + o + "物品名称已经改变为: " + name); } } } public abstract class Observable { // 用一个List来保存该对象上所有绑定的事件监听器 List<Observer> Observers = new ArrayList<Observer>(); // 定义一个方法,用于该主题上注册观察者 public void registerObserver(Observer o) { Observers.add(o); } // 定义一个方法,用于该主题上删除观察者 public void removeObserver(Observer o) { Observers.remove(o); } // 通知该主题上注册的所有观察者 public void notifyObservers(Object value) { // 遍历注册到该被观察者上的所有观察者 for (Iterator<Observer> it = Observers.iterator(); it.hasNext();) { Observer o = (Observer) it.next(); // 显示每个观察者的update方法 o.update(this, value); } } } public class Product extends Observable { private String name; private double price; public Product(String name, double price) { super(); this.name = name; this.price = price; } public Product() { super(); } public String getName() { return name; } // 当程序调用name的setter方法来修改Product的name属性时 // 程序自然触发该对象注册的所有观察者 public void setName(String name) { this.name = name; notifyObservers(name); } public double getPrice() { return price; } // 当程序调用price的setter方法来修改Product的price属性时 // 程序自然触发该对象注册的所有观察者 public void setPrice(double price) { this.price = price; notifyObservers(price); } } public class Client { public static void main(String[] args) { // 创建一个被观察者对象 Product p = new Product(); // 创建两个观察者对象 Observer no = new NameObserver(); Observer po = new PriceObserver(); // 向被观察者对象上注册上两个观察者对象 p.registerObserver(no); p.registerObserver(po); // 程序调用setter方法来改变Product的name和price属性 p.setName("笔记本"); p.setPrice(321); } }
时间: 2024-11-05 12:41:38