观察者模式与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 ...
随机推荐
- CentOS7安装redis5
1.下载/解压redisredis手册地址:http://redisdoc.com/下载路径:https://redis.io/downloadtar zxvf redis包名 2.编译&安装 ...
- BTree和B+Tree 简单区别
本篇作用于各种树之间的区别,非算法详细介绍,只是给我们这种非科班出身的一种大概的印象,现在网上更多是讲各种树的怎么实现的细节问题,本篇不涉及那么高深,如果详细了解可以查阅他人的资料,很多大神已经说的很 ...
- MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐 级之间的区别?
SQL 标准定义的四个隔离级别为: 1.read uncommited :读到未提交数据 2.read committed:脏读,不可重复读 3.repeatable read:可重读 4.seria ...
- java-反射-注解-json-xml
反射: 框架设计的灵魂 框架:半成品软件.可以再框架的基础上进行软件开发,简化代码 定义:将类的各个组成部分封装为其他对象,这就是反射机制 好处: 可以再程序运行过程中,操作这些对象 可以解耦,提高程 ...
- x64 简介
本篇原文为 introduction to x64 assembly ,如果有良好的英文基础,可以点击该链接进行下载阅读.本文为我个人:寂静的羽夏(wingsummer) 中文翻译,非机翻,著作权 ...
- iView 一周年了,同时发布了 2.0 正式版,但这只是开始...
两年前,我开始接触 Vue.js 框架,当时就被它的轻量.组件化和友好的 API 所吸引.之后我将 Vue.js 和 Webpack 技术栈引入我的公司(TalkingData)可视化团队,并经过一年 ...
- Angular2入门系列(五)———— 路由参数设置
Angular2入门系列(五)---- 路由参数设置路由配置: { path: '', component: CarProFile, children: [ { path: 'add', compon ...
- 设计模式之:抽象工厂模式AbstractFactoryPattern的实现
相比于工厂模式,抽象工厂模式的每个工厂可以创建产品系列,而不是一个产品: 抽象工厂用到的技术:接口.多态.配置文件.反射: 抽象工厂模式的设计原则: 实现客户端创建产品和使用产品的分离,客户端无须了解 ...
- SQL语句总结---表操作
https://blog.csdn.net/hallomrzhang/article/details/85010014 表的操作 1.查看表结构 desc 表名 2.创建表结构的语法 create t ...
- java中的访问控制有什么用?如何用法?请举例
9.访问控制 [新手可忽略不影响继续学习] 访问控制有什么用?在软件公司里是这么用的,我们想像一种场景,在你的类中,你编了三个私有方法,马克-to-win,别人当然都用不了,但在类外,你也是用不了的, ...