观察者模式(ObserverPattern)

    xiaoxiao2025-06-09  36

    观察者模式

    定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新;


    从上述描述中,我们可知观察者模式主旨是一对多的关系,多个隔离性的对象依赖与一个独特对象,需要获取该对象实时状态;

    这个情景如同订阅报纸行为:

    报社的业务就是出版报纸;(独特功能对象)向报社订阅报纸,有新报纸出版,就会向你送来报纸,只要你是他们的订户;当取消订阅时,它们将停止给你派送报纸;只要报社运营着,就会有人向他们订阅或者取消订阅;

    从上述类图中,可以看出观察者模式最关键实现部分是两个接口的使用;


    举个栗子: 主题接口,也可称为可观察者接口 Observerable

    public interface Observerable { //注册观察者资格 public void registerObserver(Observer observer); //取消观察者资格 public void removeObserver(Observer observer); //可观察者状态通知 public void notifyObserver(); }

    观察者接口 Observer

    public interface Observer { public void update(float temperature, float humidity, float pressure); }

    可观察者对象实现 WeatherData

    public class WeatherData implements Observerable { private float temperature; private float humidity; private float pressure; private ArrayList<Observer> observers;//观察者队列 public WeatherData() { observers = new ArrayList<Observer>(); } @Override public void registerObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { int i = observers.indexOf(observer); if(i > 0) { observers.remove(i); } } @Override public void notifyObserver() { for (Observer o : observers) { o.update(this.temperature, this.humidity, this.pressure); } } public void measurementsChange() { notifyObserver(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChange(); } }

    观察者对象 CurrentConditionDisplay

    public class CurrentConditionDisplay implements Observer, DisplayElement { private float temperature; private float humidity; private Observerable weatherData; public CurrentConditionDisplay(Observerable weatherData) { this.weatherData = weatherData; this.weatherData.registerObserver(this); } @Override public void display() { System.out.println("Current condition:" + this.temperature + "F degrees and " + this.humidity + "% humidity."); } @Override public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; display(); } }

    通过上述的解耦,当观察者对象任意增加时我们只需要调用可观察者对象registerObserver()进行注册即可得到可观察者对象的变化,同样也可以依据自身需要进行取消观察;


    对于观察者模式的实现,JDK已经提供比较完善的支持: 可观察者对象: Observable

    public class Observable { private boolean changed = false; private Vector obs; public Observable() { obs = new Vector(); } public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length-1; i>=0; i--) ((Observer)arrLocal[i]).update(this, arg); } public synchronized void deleteObservers() { obs.removeAllElements(); } protected synchronized void setChanged() { changed = true; } protected synchronized void clearChanged() { changed = false; } public synchronized boolean hasChanged() { return changed; } public synchronized int countObservers() { return obs.size(); } }

    观察者对象:

    public interface Observer { void update(Observable o, Object arg); }

    通过上面JDK源码查阅,基本所实现的功能都是一模一样的,Observable对象更是提供线程安全的保证,只是采用继承的实现方法给我们自身进行应用带来一点麻烦;

    转载请注明原文地址: https://ju.6miu.com/read-1299769.html
    最新回复(0)