1.什么是观察者模式
观察者模式(Observer),是一种行为性模型,行为型模式关注的是系统中对象之间的相互交互,解决系统在运行时对象之间的相互通信和协作,进一步明确对象的职责。相比来说,创建型模式关注对象的创建过程,结构型模式关注对象和类的组合关系。
2.模式的职责
观察者模式主要用于1对N的通知。当一个对象的状态变化时,他需要及时告知一系列对象,令他们做出相应。
实现有两种方式:
推:每次都会把通知以广播的方式发送给所有观察者,所有的观察者只能被动接收。
拉:观察者只要知道有情况即可,至于什么时候获取内容,获取什么内容,都可以自主决定。
3.模式的实现
创建Observer接口
package com.designpattern.observer;
/**
 * @description: {@link Observer}观察者接口,用来存放观察者共有方法,由{@link ObserverA},{@link ObserverB}等实现
 * @author: Codegitz
 * @create: 2020-05-19 22:16
 **/
public interface Observer {
    void update(Subject subject);
}
创建被观察者Subject类
package com.designpattern.observer;
import java.util.ArrayList;
import java.util.List;
/**
 * @description: {@link Subject}被观察对象,可注册唤醒{@link Observer}观察者
 * @author: Codegitz
 * @create: 2020-05-19 22:17
 **/
public class Subject {
    //被观察者的状态
    private int state;
    public int getState() {
        return state;
    }
    public void setState(int state) {
        this.state = state;
        this.notifyAllObserver();
    }
    //维护一个观察者列表
    private List<Observer> observers = new ArrayList<>();
    //注册
    public void registerObserver(Observer observer){
        observers.add(observer);
    }
    //移出
    public void removeObserver(Observer observer){
        observers.remove(observer);
        this.notifyAllObserver();
    }
    //更新列表里的观察者
    public void notifyAllObserver(){
        for (Observer observer: observers){
            observer.update(this);
        }
    }
}
实现Observer接口,有ObserverA, ObserverB, ObserverC三种观察者,这里只贴一份代码,其他的差不多。
package com.designpattern.observer;
/**
 * @description: 观察者A,实现{@link Observer}
 * @author: Codegitz
 * @create: 2020-05-19 22:30
 **/
public class ObserverA implements Observer {
    private Subject subject;
    @Override
    public void update(Subject subject) {
        this.subject = subject;
        getMyState();
    }
    //拼接一下当前观察者类名和更新后的state值
    public void getMyState(){
        System.out.println("[Observer name: "+this.getClass().getName()+"]--subject.getState(): "+subject.getState());
    }
}
测试类
package com.designpattern.observer;
/**
 * @description: 测试类
 * @author: Codegitz
 * @create: 2020-05-19 22:40
 **/
public class TestObserver {
    public static void main(String[] args) {
        //新建一个被观察对象
        Subject subject = new Subject();
        //三个不同的观察者
        Observer observer1 = new ObserverA();
        Observer observer2 = new ObserverB();
        Observer observer3 = new ObserverC();
        //注册三个观察者
        subject.registerObserver(observer1);
        subject.registerObserver(observer2);
        subject.registerObserver(observer3);
        //改变state的值
        System.out.println("=======change state value,set state = 100==========");
        subject.setState(100);
        //移除一个观察者
        System.out.println("============remove observer3============");
        subject.removeObserver(observer3);
        System.out.println("=======change state value,set state = 200==========");
        subject.setState(200);
    }
}
运行结果如下:
=======change state value,set state = 100==========
[Observer name: com.designpattern.observer.ObserverA]--subject.getState(): 100
[Observer name: com.designpattern.observer.ObserverB]--subject.getState(): 100
[Observer name: com.designpattern.observer.ObserverC]--subject.getState(): 100
============remove observer3============
[Observer name: com.designpattern.observer.ObserverA]--subject.getState(): 100
[Observer name: com.designpattern.observer.ObserverB]--subject.getState(): 100
=======change state value,set state = 200==========
[Observer name: com.designpattern.observer.ObserverA]--subject.getState(): 200
[Observer name: com.designpattern.observer.ObserverB]--subject.getState(): 200
  从结果可以看到,在更新被观察者的state值后,被观察者会通知所有的观察对象,把当前的被观察者对象this更新到观察者中,观察者可以进行相应的处理,我这里是直接打印了state的值,这是一种基于’’推’’模式的实现。在观察者被移除后,也会把当前状态更新一次,如果不需要这一步,只需要把removeObserver方法里的this.notifyAllObserver()方法去掉。
附完整代码,需要自取,顺便点个star。
4.观察者模式应用场景
- 关联行为场景,需要注意的是,关联行为是可拆分的,而不是“组合”关系。 
- 事件多级触发场景。 
- 跨系统的消息交换场景,如消息队列、事件总线的处理机制。消息队列应该是很经典的一种实践了。 
 
		