概述

观察者模式又被称为发布-订阅(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实现的更多相关文章

  1. 观察者模式与Guava EventBus

    观察者模式 结构图 代码实现 public abstract class Subject { private List<Observer> observerList = new Array ...

  2. 设计模式:Observer(观察者)—— Guava EventBus

    本文分为三个部分:   Observer(观察者) Guava EventBus详解 Guava EventBus使用示例   1. Observer(观察者)   1.1 背景   我们设计系统时, ...

  3. Guava 12:Guava EventBus源码剖析

    一.架构速读 传统上,Java的进程内事件分发都是通过发布者和订阅者之间的显式注册实现的.设计EventBus就是为了取代这种显示注册方式,使组件间有了更好的解耦.EventBus不是通用型的发布-订 ...

  4. Guava学习笔记:Google Guava 类库简介

    http://www.cnblogs.com/peida/tag/Guava/ Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, cachin ...

  5. Google Guava官方教程(中文版)

    Google Guava官方教程(中文版) 原文链接  译文链接 译者: 沈义扬,罗立树,何一昕,武祖  校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库, ...

  6. 初探Google Guava

    Guava地址:https://github.com/google/guava 第一次接触我是在16年春github上,当时在找单机查缓存方法,google guava当初取名是因为JAVA的类库不好 ...

  7. Google Guava新手教程

         以下资料整理自网络 一.Google Guava入门介绍 引言 Guavaproject包括了若干被Google的 Java项目广泛依赖 的核心库,比如:集合 [collections] . ...

  8. Google Guava 类库简介

    Guava 是一个 Google开发的 基于java的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency librar ...

  9. 开源介绍:Google Guava、Google Guice、Joda-Time

    一.Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency lib ...

随机推荐

  1. 面向对象编程(C++篇4)——RAII

    目录 1. 概述 2. 详论 2.1. 堆.栈.静态区 2.2. 手动管理资源的弊端 2.3. 间接使用 2.4. 自下而上的抽象 3. 总结 4. 参考 1. 概述 在前面两篇文章<面向对象编 ...

  2. 机械学习笔记1 -> Solidworks三维产品设计与建模1 | 建模基础入门

    学习之余,课余了解一点点,作为爱好,妄想以后能够设计机甲出来. 学习来源是Solidworks三维产品设计与建模 00 工作界面介绍 00-1 概览 有时菜单栏和工具栏会重叠在一起,只有点击左侧三角才 ...

  3. eureka自我保护机制是什么?

    当Eureka Server 节点在短时间内丢失了过多实例的连接时(比如网络故障或频繁启动关闭客户端)节点会进入自我保护模式,保护注册信息,不再删除注册数据,故障恢复时,自动退出自我保护模式.

  4. canvas系列教程03-柱状图项目1

    弄了一堆线方块和函数,感觉挺玄乎,然并卵.我们直接写个项目看看. canvas一个比较拽的应用就是图表和游戏,我们从浅入深,先玩图表,图表我们今天说一个最简单柱状图. 柱状图很多人用百度的echars ...

  5. mapreduce分区

    本次分区是采用项目垃圾分类的csv文件,按照小于4的分为一个文件,大于等于4的分为一个文件 源代码: PartitionMapper.java: package cn.idcast.partition ...

  6. Android回到页面并刷新数据

    通过对Android Activity的生命周期的了解,需要在后退页面重写onResume()的方法. 建立自己更新数据的函数,并在onCreate()方法中调用. @Override protect ...

  7. vue后台管理系统组件弹窗

    //addFormVisibleIcon可在data中设置true与falsehttps://element.eleme.io/#/zh-CN/component/installation <e ...

  8. EMS查看邮箱容量限制的方法

    以Exchange管理员身份打开EMS控制台.在PowerShell命令行提示符下,输入以下命令. Get-MailboxDatabase | FL name,IssueWarningQuota,Pr ...

  9. animate.css使用

    解决 使用jquery单纯添加类不能出现动画 使用jQuery向元素中添加类制作动画的时候,需要使用setTimeout实现,因为动画需要从一个状态到另外一个状态!时间设置为0

  10. Spring集成web环境(使用封装好的工具)

    接上文spring集成web环境(手动实现) ##########代码接上文############# spring提供了一个监听器ContextLoaderListener对上述功能的封装,该监听器 ...