观察者模式与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]-数学老师来了:停止写作业,接着玩游戏
观察者模式与Google Guava EventBus实现的更多相关文章
- 观察者模式与Guava EventBus
		观察者模式 结构图 代码实现 public abstract class Subject { private List<Observer> observerList = new Array ... 
- 设计模式:Observer(观察者)—— Guava EventBus
		本文分为三个部分: Observer(观察者) Guava EventBus详解 Guava EventBus使用示例 1. Observer(观察者) 1.1 背景 我们设计系统时, ... 
- Guava 12:Guava EventBus源码剖析
		一.架构速读 传统上,Java的进程内事件分发都是通过发布者和订阅者之间的显式注册实现的.设计EventBus就是为了取代这种显示注册方式,使组件间有了更好的解耦.EventBus不是通用型的发布-订 ... 
- Guava学习笔记:Google Guava 类库简介
		http://www.cnblogs.com/peida/tag/Guava/ Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, cachin ... 
- Google Guava官方教程(中文版)
		Google Guava官方教程(中文版) 原文链接 译文链接 译者: 沈义扬,罗立树,何一昕,武祖 校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库, ... 
- 初探Google Guava
		Guava地址:https://github.com/google/guava 第一次接触我是在16年春github上,当时在找单机查缓存方法,google guava当初取名是因为JAVA的类库不好 ... 
- Google Guava新手教程
		以下资料整理自网络 一.Google Guava入门介绍 引言 Guavaproject包括了若干被Google的 Java项目广泛依赖 的核心库,比如:集合 [collections] . ... 
- Google Guava 类库简介
		Guava 是一个 Google开发的 基于java的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency librar ... 
- 开源介绍:Google Guava、Google Guice、Joda-Time
		一.Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency lib ... 
随机推荐
- Spring Boot 需要独立的容器运行吗?
			可以不需要,内置了 Tomcat/ Jetty 等容器. 
- ruoyi首次使用常见问题的解决方案
			1.导入项目之后,下载依赖包之后,模块的依赖项飘红(我这里无法复现,当参考图吧) 解决方法: 2.ruoyi框架代码生成之后,需要自己进行替换到指定位置.相应的官方文档位置,否则,可能会出现404,访 ... 
- short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?
			对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算结果也是int 型,需要强制转换类型才能赋值给short型.而short s1 = 1; s1 += 1;可 ... 
- 使用 rabbitmq 的场景?
			1.服务间异步通信 2.顺序消费 3.定时任务 4.请求削峰 
- Java程序要操作数据库,一定要使用JDBC技术吗?
			<!-- MySQL驱动,连接数据库用,由数据库厂商提供 --> <dependency> <groupId>mysql</groupId> <a ... 
- synchronized 关键字的用法?
			synchronized 关键字可以将对象或者方法标记为同步,以实现对对象和方法的互 斥访问,可以用 synchronized(对象) { - }定义同步代码块,或者在声明方法时 将 synchron ... 
- 如何通过HibernateDaoSupport将Spring和Hibernate  结合起来?
			用 Spring 的 SessionFactory 调用 LocalSessionFactory.集成过程分三步: 配置 the Hibernate SessionFactory. 继承 Hibern ... 
- 学习openstack(七)
			相关资料: https://www.cnblogs.com/shhnwangjian/category/942049.html https://www.cnblogs.com/goodcook/cat ... 
- SpringCloudAlibaba 微服务讲解(四)Sentinel--服务容错(二)
			4.7 Sentinel 规则 4.7.1 流控规则 流量控制,其原理是监控应用流量的QPS(每秒查询率)或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的榴莲高峰冲垮,从而保障应用 ... 
- Python中的numpy库介绍!
			转自:https://blog.csdn.net/codedz/article/details/82869370 机器学习算法中大部分都是调用Numpy库来完成基础数值计算的.安装方法: pip3 i ... 
