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的内容

  • 相关阅读:
    mysql 中 时间函数 now() current_timestamp() 和 sysdate() 比较
    在spring boot 中使用itext和itextrender生成pdf文件
    dockerfile构建的镜像
    在linux环境下使用itext生成pdf
    在spring data jpa中使用自定义转换器之使用枚举转换
    Sping Boot返回Json格式自定义
    【强化学习RL】model-free的prediction和control — MC, TD(λ), SARSA, Q-learning等
    【强化学习RL】必须知道的基础概念和MDP
    【GAN与NLP】GAN的原理 —— 与VAE对比及JS散度出发
    【NLP】使用bert
  • 原文地址:https://www.cnblogs.com/weixk/p/13161113.html
Copyright © 2011-2022 走看看