观察者模式,也叫发布-订阅模式

适用场景:被观察者改变时,会通知观察者。观察者可以通过注册,成为一个观察者。 image

/**
 * 观察者需要实现的接口
 */
public interface Observer {
    void response(); //当被观察者变化时,做出反应的方法
}

/**
 * 具体观察者1
 */
public class ObserverImpl implements Observer {
    //收到通知后的反应
    public void response() {
        System.out.println("我收到了通知!我是:" + this.getClass().getName() + "的对象");
    }
}

/**
 * 具体观察者2
 */
public class ObserverImpl2 implements Observer {
    //收到通知后的反应
    public void response() {
        System.out.println("我收到了通知!我是:" + this.getClass().getName() + "的对象");
    }
}

/**
 * 被观察者的抽象类
 */
public abstract class Subject {
    //存放观察者
    protected List<Observer> observers = new ArrayList<Observer>();

    //注册观察者
    abstract void registeObserver(Observer observer);

    //删除观察者
    abstract void removeObserver(Observer observer);

    //通知观察者
    abstract void notifyObservers();
}

/**
 * 具体被观察者
 */
public class SubjectImpl extends Subject {
    void registeObserver(Observer observer) {
        observers.add(observer);
    }

    void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    //通知所有观察者
    void notifyObservers() {
        for (Observer observer : observers) {
            observer.response();
        }
    }
}

/**
 * 演示
 */
public class Demo {
    public static void main(String[] args) {
        //被观察者
        SubjectImpl subject = new SubjectImpl();

        //两种不同类型的观察者
        Observer observer1 = new ObserverImpl();
        Observer observer2 = new ObserverImpl2();

        //注册
        subject.registeObserver(observer1);
        subject.registeObserver(observer2);

        //通知
        subject.notifyObservers();

    }
}

输出: image

此时,可随意增加不同的观察者,对被观察者的通知进行不同的反应。

优点

解除耦合,让耦合的双方都依赖于抽象,从而使得各自的变换都不会影响另一边的变换。

缺点

在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现