设计模式初解——观察者模式

200 阅读2分钟

前言

观察者,即时observer,总结来说就是一个当一个被观察的对象的状态发生变化时,会通知相应的观察者对象。 观察者模式定义了四种角色:抽象主题、具体主题、抽象观察者、具体观察者

  1. 抽象主题(Subject):通常为接口或抽象类,定义一系列操作,如订阅,取消订阅,通知等方法
  2. 具体主题(Concrete Subject):具体主题,继承或实现抽象主题,实现相应的逻辑,如维护与观察者的关系,将自身的状态变化告知观察者。
  3. 抽象观察者(Observer):定义观察者行为
  4. 具体观察者(Concrete Observer):实现观察者行为,实现收到被观察者的通知后将要处理的逻辑

实例

场景

微信公众号消息的订阅与推送,我订阅了公众号,我就是观察者,公众号是被观察者,当公众号发表了新文章时,即被观察者的状态发生改变,公众号会给我推送通知

/**
 * 抽象观察者
 */
public interface IObserver {
    void update(String message);
}
/**
 * 抽象主题
 */
public interface ISubject {
    //订阅
    public void registerObserver(IObserver observer);
    //取消订阅
    public void unregisterObserver(IObserver observer);
    //通知
    public void notifyObserver(String message);
}
/**
 * 具体观察者
 */
public class Observer implements IObserver {
    @Override
    public void update(String message) {
        System.out.println("我收到了通知:"+message);
    }
}
/**
 * 具体主题:实现一系列逻辑操作,维护与观察者的关系
 */
public class Subject implements ISubject {

    private List<IObserver> list = new ArrayList<>();

    @Override
    public void registerObserver(IObserver observer) {
        list.add(observer);
    }

    @Override
    public void unregisterObserver(IObserver observer) {
        list.remove(observer);
    }

    @Override
    public void notifyObserver(String message) {
        list.forEach(o -> o.update(message));
    }
}

测试: 输出结果:

总结

观察者模式在有的书里又称为发布/订阅模式,当需要对某个对象的状态进行检测时,则可以使用该设计模式。例如观察检测温度超过某阈值时,向APP推送短信提醒。

与MQTT协议的话题订阅推送其实是类似的,基本流程都是先订阅维护一个关系,在有状态变化时则给相应的观察者推送数据,唯一不同的是观察与被观察的关系是由谁来维护。

Java中的观察者模式

Java内置了观察者模式

Java提供了一个Observable类,顾名思义可知“可观察的”。当你有一个类需要被观察时,需要继承此类。 Java还提供了一个Observer接口,顾名思义可知“观察者”。当你有一个类需要观察别的类时,需要实现此接口。

public class Fire extends Observable {
    private String temperature;

    public void temperatureChange() {
        setChanged();
        notifyObservers();
    }

    public String getTemperature() {
        return temperature;
    }

    public void setTemperature(String temperature) {
        this.temperature = temperature;
        temperatureChange();
    }
}
public class Watcher implements Observer{

    private Observable observable;

    private String temperature;

    public Watcher(Observable observable) {
        this.observable = observable;
        observable.addObserver(this);
    }

    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof Fire) {
            Fire fire = (Fire) o;
            this.temperature = fire.getTemperature();
            display();
        }
    }

    public void display() {
        System.out.println(this.toString());
    }

    @Override
    public String toString() {
        return "Fire:" + temperature;
    }
}

测试: 输出结果: