zoukankan      html  css  js  c++  java
  • 观察者模式

    一、观察者模式介绍

    1、定义与类型

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

    2、适用场景

    关联行为场景,建立一套触发机制
    例如:朋友圈点赞后的其他人评论提醒,网店商品的降价提醒,论坛帖子被回复的提醒

    3、优点

    观察者和被观察者之间建立一个抽象的耦合
    观察者模式支持广播通信

    4、缺点

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

    二、代码示例

    模拟场景:学生在课程上提了问题,老师作为观察者,需要接收到问题,其中老师(观察者)可能有多个。
    JDK本身就提供了观察者模式的实现支持
    通知者(可被观察):java.util.Observable
    观察者:java.util.Observer

    问题类:

    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 Course extends Observable {
        private String courseName;
    
        public String getCourseName() {
            return courseName;
        }
    
        public Course(String courseName) {
            this.courseName = courseName;
        }
    
        public void produceQuestion(Course course, Question question){
            System.out.println(question.getUserName() + " 在 " + course.getCourseName() + " 提交了一个问题");
            // 调用 Observable 的方法
            setChanged();
            notifyObservers(question);
        }
    }
    

    老师类:

    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());
        }
    }
    

    测试类:

    public class Test {
        public static void main(String[] args) {
            Course course = new Course("观察者模式");
            Teacher teacher1 = new Teacher("Alpha");
            Teacher teacher2 = new Teacher("Beta");
    
            // 添加观察者
            course.addObserver(teacher1);
            course.addObserver(teacher2);
    
            // 业务逻辑代码
            Question question = new Question();
            question.setUserName("某学生");
            question.setQuestionContent("JAVA的主函数如何编写");
            
            course.produceQuestion(course, question);
        }
    }
    

    输出:
    某学生 在 观察者模式 提交了一个问题
    Beta 老师的 观察者模式 课程接收到 某学生 提交的问题:JAVA的主函数如何编写
    Alpha 老师的 观察者模式 课程接收到 某学生 提交的问题:JAVA的主函数如何编写

    三、源码示例

    Guava中的GuavaEvent

    测试:
    观察者类:

    import com.google.common.eventbus.Subscribe;
    
    public class GuavaEvent {
        @Subscribe
        public void subscribe(String str) {
            // 业务逻辑
            System.out.println("执行subscribe,传入的参数为 " + str);
        }
    }
    

    测试类:

    public class GuavaEventTest {
        public static void main(String[] args) {
            EventBus eventBus = new EventBus();
            GuavaEvent guavaEvent = new GuavaEvent();
            eventBus.register(guavaEvent);
            eventBus.post("post的内容");
        }
    }
    

    输出:执行subscribe,传入的参数为 post的内容

  • 相关阅读:
    SpringBoot实现原理
    常见Http状态码大全
    forward(转发)和redirect(重定向)有什么区别
    1094. Car Pooling (M)
    0980. Unique Paths III (H)
    1291. Sequential Digits (M)
    0121. Best Time to Buy and Sell Stock (E)
    1041. Robot Bounded In Circle (M)
    0421. Maximum XOR of Two Numbers in an Array (M)
    0216. Combination Sum III (M)
  • 原文地址:https://www.cnblogs.com/weixk/p/13161113.html
Copyright © 2011-2022 走看看