设计模式之观察者模式

定义

定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖者(观察者)都会收到通知并更新。

类型

行为型

适用场景

①、关联行为场景,建立一套触发机制。

优缺点

优点:
①、观察者和被观察者之间建立了一个抽象的耦合。
②、观察者模式支持广播通信。

缺点:
①、观察者之间有过多的细节依赖、提高时间消耗及程序复杂度。
②、使用要得当,要避免循环调用。

代码实现

案例:老师在每节课的课后都会收到同学提出的问题。这里课程就是一个被观察者,而老师作为一个观察者。
首先创建一门课程

public class Course extends Observable {

    private String courseName;

    public Course(String courseName) {
        this.courseName = courseName;
    }

    public String getCourseName() {
        return courseName;
    }

    public void produceQuestion(Course course, Question question) {
        System.out.println(question.getUserName() + "在" + course.getCourseName() + "这门课程提出了问题");
        setChanged();
        notifyObservers(question);
    }
}

这里继承Observable这个类,表明这是一个被观察者。
setChanged()方法:标记此 Observable对象为已改变的对象。
notifyObservers(question):通知所有观察者。
接下来创建问题类

public class Question {

    private String userName;
    private String questionContent;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getQuestionContent() {
        return questionContent;
    }

    public void setQuestionContent(String questionContent) {
        this.questionContent = questionContent;
    }
}

这个类提供了提出问题人的名字和问题内容。
最后创建观察者

public class Teacher implements Observer {

    private String teacherName;

    public Teacher(String teacherName) {
        this.teacherName = teacherName;
    }

    @Override
    public void update(Observable o, Object arg) {
        Course course = (Course) o;
        Question question = (Question) arg;
        System.out.println(teacherName + "老师的" + course.getCourseName() + "课程收到了" + question.getUserName() + "同学提出的:" + question.getQuestionContent() + "这个问题");
    }
}

Observer这是一个接口,实现这个类,表明Teacher是一个观察者,需要实现update()这个方法。当有被观察者发生变化时,自动调用update()这个方法,o是被观察者对象,arg是被观察者传过来的发生变化的数据对象。
编写测试类

public class MainTest {

    public static void main(String[] args) {
        Course course = new Course("Java设计模式");
        Teacher teacher1 = new Teacher("qfcwx");
        Teacher teacher2 = new Teacher("清风");

        // 添加观察者
        course.addObserver(teacher1);
        course.addObserver(teacher2);

        // 业务逻辑代码
        Question question = new Question();
        question.setUserName("小明");
        question.setQuestionContent("观察者模式该怎么学习呢?");

        course.produceQuestion(course, question);
    }
}

这里设定了两个老师作为观察者来观察课程的变化。
输出结果:

C:\android\java\jdk1.8\bin\java.exe
小明在Java设计模式这门课程提出了问题
清风老师的Java设计模式课程收到了小明同学提出的:观察者模式该怎么学习呢?这个问题
qfcwx老师的Java设计模式课程收到了小明同学提出的:观察者模式该怎么学习呢?这个问题

相关源码

1. Jdk中的EventListener监听器(发布订阅模式)
2. 谷歌Guava中的EventBus

参考链接
https://coding.imooc.com/learn/list/270.html

上一篇:CO7216 Semantic Web


下一篇:vue列表展开收起效果