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

这就好比一个办在线教育的老师(OnlineTeacher)和线下的若干学生(localStudent1, localStudent2, localStudent3 ...)之间的关系。

当这个老师在线上发布了一条消息之后,他所有的学生都会收到通知,并可以根据这条消息的内容来实现对应的更新。

观察者模式类图

为了实现松耦合设计,OnlineTeacher对象只需要实现Subject接口,并实现其中规定的三个方法即可:

  1. registerObserver(); //注册观察者
  2. removeObserver(); //取消注册观察者
  3. notifyObserver(); //通知观察者

Subject接口:

public interface Subject {    //Subject接口中的三个方法,用于注册、移除和通知observers    void registerObserver(Observer observer);    void removeObserver(Observer observer);    //以上两个方法都需要一个observer对象作为变量,以实现注册或被删除    void notifyObservers();}

同时,OnlineTeacher对象还需要一个数据结构,来存储已经注册的学生对象。

OnlineTeacher类

public class OnlineTeacher implements Subject {    //建立一个数据结构来存储注册过的observer对象    private ArrayList<Observer> observerArrayList;    //用message来模拟老师讲课    private String message;    //OnlineTeacher类的构造器,生成该对象时,会初始化一个observerArrayList    public OnlineTeacher() {        observerArrayList = new ArrayList<>();    }    @Override    public void registerObserver(Observer observer) {        observerArrayList.add(observer);    }    @Override    public void removeObserver(Observer observer) {        int i = observerArrayList.indexOf(observer);        if (i > 0) {            observerArrayList.remove(i);        }    }    //实现notifyObservers(),实质上就是遍历observerArrayList,让其中的每一个observer对象调用他们的update()方法    @Override    public void notifyObservers() {        for (int i = 0; i < observerArrayList.size(); i++) {            observerArrayList.get(i).updates(message);        }    }    //OnlineTeacher有一个方法,setMessage()    public void setMessage(String newMessage) {        this.message = newMessage;        messageChanged(); //message赋值之后,调用messageChanged()方法    }    //还有一个方法,messageChanged,在此方法中调用notifyObservers()    public void messageChanged() {        notifyObservers();    }}

而所有的学生对象只需要实现Observer接口即可成为“观察者”。
所有的观察者只需要保有一个OnlineTeacher对象的引用,便可以在各自的构造器中实现对自身的注册。

Observer接口

public interface Observer {    void updates(String message);}

用来模拟的localStudent对象们

localStudent1类:

public class LocalStudent1 implements Observer {    private Subject onlineTeacher;    //构造器需要OnlineTeacher对象(也就是subject),用来注册自己    public LocalStudent1(Subject onlineTeacher) {        this.onlineTeacher = onlineTeacher;        onlineTeacher.registerObserver(this);    }    @Override    public void updates(String message) {        System.out.println("localStudent1从onlineTeacher那儿得到的message是:" +                message +','+                "我领悟到的是:女子和小人一样");    }}

localStudent2类:

public class LocalStudent2 implements Observer {    private Subject onlineTeacher;    public LocalStudent2(Subject onlineTeacher) {        this.onlineTeacher = onlineTeacher;        onlineTeacher.registerObserver(this);    }    @Override    public void updates(String message) {        System.out.println("localStudent2从onlineTeacher那儿得到的message是:" +                message +','+                "我领悟到的是:这话还有后半句——近之则不逊,远之则怨");    }}

localStudent3类:

public class LocalStudent3 implements Observer{    private Subject onlineTeacher;    public LocalStudent3(Subject onlineTeacher) {        this.onlineTeacher = onlineTeacher;        onlineTeacher.registerObserver(this);    }    @Override    public void updates(String message) {        System.out.println("localStudent3从onlineTeacher那儿得到的message是:" +                message +','+                "我领悟到的是:一个人对他亲近了,他对你不尊重,疏远了却又有怨言!");    }}

运行ObserverPatternRunDemo.java

public class ObserverPatternRunDemo {    public static void main (String [] args){        OnlineTeacher onlineTeacher = new OnlineTeacher();        LocalStudent1 localStudent1 = new LocalStudent1(onlineTeacher);        LocalStudent2 localStudent2 = new LocalStudent2(onlineTeacher);        LocalStudent3 localStudent3 = new LocalStudent3(onlineTeacher);        onlineTeacher.setMessage("子曰:唯女子与小人难养也");    }}

运行时,以localStudent1对象为例。生成该对象时,会调用onlineTeacher对象的registerObserver()方法,将其自身加入到onlineTeacher对象的observerArrayList当中。
当onlineTeacher对象调用setMessage("子曰:唯女子与小人难养也");时,相当于message的值为子曰:唯女子与小人难养也

//OnlineTeacher.java中定义的setMessage()和messageChanged()方法...  //OnlineTeacher有一个方法,setMessage()    public void setMessage(String newMessage) {        this.message = newMessage;        messageChanged(); //message赋值之后,调用messageChanged()方法    }    //还有一个方法,messageChanged,在此方法中调用notifyObservers()    public void messageChanged() {        notifyObservers();    }}...

根据onlineTeacher类中定义的方法,应有:
先调用messageChanged()方法,然后会调用notifyObservers()方法,而notifyObservers()方法会遍历所有的Observer对象,并调用他们的update()方法:

  //实现notifyObservers(),实质上就是遍历observerArrayList,让其中的每一个observer对象调用他们的update()方法    @Override    public void notifyObservers() {        for (int i = 0; i < observerArrayList.size(); i++) {            observerArrayList.get(i).updates(message);        }    }

3个localStudent对象的update()方法
localStudent1.update();

   @Override    public void updates(String message) {        System.out.println("localStudent1从onlineTeacher那儿得到的message是:" +                message +','+                "我领悟到的是:女子和小人一样");    }}

localStudent2.update();

  @Override    public void updates(String message) {        System.out.println("localStudent2从onlineTeacher那儿得到的message是:" +                message +','+                "我领悟到的是:这话还有后半句——近之则不逊,远之则怨");    }
**localStudent3.update();**
   @Override    public void updates(String message) {        System.out.println("localStudent3从onlineTeacher那儿得到的message是:" +                message +','+                "我领悟到的是:一个人对他亲近了,他对你不尊重,疏远了却又有怨言!");    }

Demo运行的结果

localStudent1从onlineTeacher那儿得到的message是:子曰:唯女子与小人难养也,我领悟到的是:女子和小人一样localStudent2从onlineTeacher那儿得到的message是:子曰:唯女子与小人难养也,我领悟到的是:这话还有后半句——近之则不逊,远之则怨localStudent3从onlineTeacher那儿得到的message是:子曰:唯女子与小人难养也,我领悟到的是:一个人对他亲近了,他对你不尊重,疏远了却又有怨言!