• 观察者模式与Google Guava EventBus实现


    概述

    观察者模式又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种。
    它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

    简单实现

    主题接口和观察者接口

    //主题接口
    public interface Subject {
        //登记
        void register(Observer observer);
        //注销登记
        void unregister(Observer observer);
        //通知
        void notify();
    }
    
    //观察者接口
    public interface Observer {
        //更新
        void update();
    }
    

    实现类

    //主题实现类
    public class TeacherComeSubject implements Subject {
        private List<Observer> observerList = new ArrayList<>();
    
        @Override
        public void register(Observer observer) {
            observerList.add(observer);
        }
    
        @Override
        public void unregister(Observer observer) {
            observerList.remove(observer);
        }
    
        @Override
        public void notfiy() {
            for (Observer observer : observerList) {
                observer.update();
            }
        }
    }
    
    //打游戏学生观察者
    public class StudentPlayGameObserver implements Observer {
        @Override
        public void update() {
            System.out.println("停止打游戏,马上写作业");
        }
    }
    //聊天学生观察者
    public class StudentChatObserver implements Observer {
        @Override
        public void update() {
            System.out.println("停止聊天,马上写作业");
        }
    }
    

    客户端

    public static void main( String[] args ) {
    	Subject subject = new TeacherComeSubject();
    	Observer studentChatObserver = new StudentChatObserver();
    	Observer studentPlayGameObserver = new StudentPlayGameObserver();
    
    	subject.register(studentChatObserver);
    	subject.register(studentPlayGameObserver);
    
    	//老师来了
    	subject.notfiy();
    }
    

    执行结果:

    停止聊天,马上写作业
    停止打游戏,马上写作业
    

    Google Guava 实现

    EventBus是Guava中的事件处理机制,是观察者模式的优雅实现,使用起来也非常的简单。
    它主要由三部分组成:事件总线、事件、事件监听

    它的缺点是:只能单进程使用,项目异常重启或者退出不保证消息持久化。如果要支持分布式,还是要用MQ。

    0. 引入依赖

    <dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>20.0</version>
        </dependency>
    </dependencies>
    

    1. 事件总线

    //静态工具类
    public class EventBusCenter{
    	private static final EventBus eventBus = new EventBus();
    	
         /**
         * 登记事件监听
         *
         * @param eventListener
         */
        public static void register(EventListener eventListener) {
            eventBus.register(eventListener);
        }
    
         /**
         * 注销登记事件监听
         *
         * @param eventListener
         */
        public static void unregister(EventListener eventListener) {
            eventBus.unregister(eventListener);
        }
    
         /**
         * 推送事件
         *
         * @param eventListener
         */
        public static void post(Event event) {
            eventBus.post(event);
        }
    }
    

    2. 事件

    //事件接口
    public interface Event {
        String getName();
    }
    
    /**
     * 老师来了事件
     */ 
    public class TeacherComeEvent implements Event {
        /**
         * 事件名称
         */
        private String name;
    
        public TeacherComeEvent(String name) {
            this.name = name;
        }
    
        @Override
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    /**
     * 老师离开事件
     */
    public class TeacherLeaveEvent implements Event {
        private String name;
    
        public TeacherLeaveEvent(String name) {
            this.name = name;
        }
    
        @Override
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    3. 事件监听

    //事件监听接口
    public interface EventListener {
    
    }
    
    //老师事件监听,包括老师来了事件、老师走了事件
    public class TeacherEventListener implements EventListener {
    
        /**
         * 监听老师来了事件
         *
         * @param event
         */
        @Subscribe
        public void teacherCome(TeacherComeEvent event) {
            System.out.println(Thread.currentThread() + "-" + event.getName() + ":停止游戏,假装写作业");
        }
    
        /**
         * 监听老师走了事件
         *
         * @param event
         */
        @Subscribe
        public void teacherLeave(TeacherLeaveEvent event) {
            System.out.println(Thread.currentThread() + "-" + event.getName() + ":停止写作业,接着玩游戏");
        }
    }
    

    使用

    //事件监听器
    EventListener eventListener = new TeacherEventListener();
    //登记事件监听器
    EventBusCenter.register(eventListener);
    //推送事件
    EventBusCenter.post(new TeacherComeEvent("数学老师来了"));
    EventBusCenter.post(new TeacherLeaveEvent("数学老师走了"));
    

    执行结果:

    Thread[main,5,main]-数学老师来了:停止游戏,假装写作业
    Thread[main,5,main]-数学老师来了:停止写作业,接着玩游戏
    

    异步处理

    比如说,事件发生之后,不想立即处理,而是异步处理,只需换一个 EventBus 即可

    //修改EventBusCenter
    //private static final EventBus eventBus = new EventBus();
    //异步处理事件
    private static final EventBus eventBus = new AsyncEventBus(Executors.newCachedThreadPool());
    

    观察此时的执行结果:

    Thread[pool-1-thread-1,5,main]-数学老师来了:停止游戏,假装写作业
    Thread[pool-1-thread-2,5,main]-数学老师来了:停止写作业,接着玩游戏
    
  • 相关阅读:
    win10补丁导致打印机无法共享
    EdgexGo2.0学习-14 EdgeX2.0 AppService导出到Mqtt
    EdgexGo2.0学习-13 EdgeX2.0 编译Appservice
    winform程序在系统缩放150%时右边留空白问题解决办法
    Linux嵌入式串口转网络
    Win10 磁盘变成文件夹
    Win10下使用Gitblit
    JMeter学习笔记——Web接口测试(webservice)
    jmeter之__RandomFromMultipleVars函数使用详解
    jmeter——参数化——$__RandomFromMultipleVars()函数
  • 原文地址:https://www.cnblogs.com/haicheng92/p/16098845.html
Copyright © 2020-2023  润新知