观察者模式

栏目: 后端 · 发布时间: 5年前

内容简介:这就好比一个办在线教育的老师(OnlineTeacher)和线下的若干学生(localStudent1, localStudent2, localStudent3 ...)之间的关系。当这个老师在线上发布了一条消息之后,他所有的学生都会收到通知,并可以根据这条消息的内容来实现对应的更新。

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

这就好比一个办在线教育的老师(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是:子曰:唯女子与小人难养也,我领悟到的是:一个人对他亲近了,他对你不尊重,疏远了却又有怨言!

以上所述就是小编给大家介绍的《观察者模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Dream Machine

The Dream Machine

M. Mitchell Waldrop / Penguin Books / 2002-8 / USD 16.00

While most people may not be familiar with the name J. C. R. Licklider, he was the guiding spirit behind the greatest revolution of the modern era. At a time when most computers were big, ponderous ma......一起来看看 《The Dream Machine》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具