Guava ---- EventBus事件驱动模型
在软件开发过程中, 难免有信息的共享或者对象间的协作。 怎样让对象间信息共享高效, 而且耦合性低。 这是一个难题。 而耦合性高将带来编码改动牵一发而动全身的连锁效应。 Spring的风靡正是由于攻克了高耦合问题。 本篇介绍的EventBus中也用到了Spring中的依赖注入。 来进行对象和对象间的解耦(如@Subscribe)。
Guava解决高耦合採用的是事件驱动模型的思路。 对象能够订阅(subscribe)特定的事件或者公布(publish)特定的事件去被消费。 从以下的代码能够看出, EventBus对生产者和消费者是透明的, 它无需知道他们的类型。 从而实现了解耦。
TradeAccountEvent: 基本对象兼測试类
package com.wenniuwuren.eventbus;
import com.google.common.eventbus.EventBus; import java.util.Date; /**
* 无论什么时候买卖交易运行, 都会产生一个TradeAccountEvent实例
*/
public class TradeAccountEvent {
private double amount;
private Date tradeExecutionTime;
private String tradeType;
private String tradeAccount; public TradeAccountEvent(String account, double amount,
Date tradeExecutionTime, String tradeType) {
this.amount = amount;
this.tradeExecutionTime =tradeExecutionTime;
this.tradeAccount = account;
this.tradeType = tradeType;
} public static void main(String[] args) {
// 消费者和生产者依据EventBus对象来一一相应
EventBus eventBus1 = new EventBus();
SimpleTradeAuditor simpleTradeAuditor = new SimpleTradeAuditor(eventBus1);
SimpleTradeExecutor simpleTradeExecutor = new SimpleTradeExecutor(eventBus1);
simpleTradeExecutor.executeTrade("zhangsan", 10, "Money"); System.out.println("----This is devil dividing line------"); EventBus eventBus2 = new EventBus();
BuySellTradeExecutor buySellTradeExecutor = new BuySellTradeExecutor(eventBus2);
AllTradesAuditor allTradesAuditor = new AllTradesAuditor(eventBus2);
buySellTradeExecutor.executeTrade("lisi", 100, "SELL");
System.out.println("---------------------");
buySellTradeExecutor.executeTrade("wangwu", 1000, "BUY");
}
}
AllTradesAuditor:依据不同生产者订阅不同内容
package com.wenniuwuren.eventbus; import java.util.List; import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe; public class AllTradesAuditor {
private List<BuyEvent> buyEvents = Lists.newArrayList();
private List<SellEvent> sellEvents = Lists.newArrayList(); public AllTradesAuditor(EventBus eventBus) {
eventBus.register(this);
} @Subscribe
public void auditSell(SellEvent sellEvent) {
sellEvents.add(sellEvent);
System.out.println("Received TradeSellEvent " + sellEvent);
} @Subscribe
public void auditBuy(BuyEvent buyEvent) {
buyEvents.add(buyEvent);
System.out.println("Received TradeBuyEvent " + buyEvent);
}
}
BuyEvent:
package com.wenniuwuren.eventbus; import java.util.Date; /**
* 购买事件
* @author wenniuwuren
*
*/
public class BuyEvent extends TradeAccountEvent {
public BuyEvent(String tradeAccount, double amount,
Date tradExecutionTime) {
super(tradeAccount, amount, tradExecutionTime, "BUY");
}
}
SellEvent:
package com.wenniuwuren.eventbus; import java.util.Date; /**
* 销售事件
* @author wenniuwuren
*
*/
public class SellEvent extends TradeAccountEvent {
public SellEvent(String tradeAccount, double amount, Date tradExecutionTime) {
super(tradeAccount, amount, tradExecutionTime, "SELL");
}
}
BuySellTradeExecutor: 分类型(BUY、SELL)公布事件
package com.wenniuwuren.eventbus; import java.util.Date; import com.google.common.eventbus.EventBus; /**
* 分类型(SELL BUY)运行器
* @author wenniuwuren
*
*/ public class BuySellTradeExecutor { private EventBus eventBus; public BuySellTradeExecutor(EventBus eventBus) { this.eventBus = eventBus;
} private TradeAccountEvent processTrade(String tradeAccount, double amount,
String tradeType) {
Date executionTime = new Date();
String message = String.format("Processed trade for" + tradeAccount
+ "of amount" + amount + "type" + tradeType + "@"
+ executionTime);
TradeAccountEvent tradeAccountEvent;
if (tradeType.equals("BUY")) {
tradeAccountEvent = new BuyEvent(tradeAccount, amount,
executionTime);
} else {
tradeAccountEvent = new SellEvent(tradeAccount, amount,
executionTime);
}
System.out.println(message);
return tradeAccountEvent;
} public void executeTrade(String tradeAccount, double amount, String tradeType) {
TradeAccountEvent tradeAccountEvent = processTrade(tradeAccount, amount, tradeType);
// 公布, 通知订阅者
eventBus.post(tradeAccountEvent);
}
}
SimpleTradeAuditor: 最简单的事件消费者(或者说订阅者)
package com.wenniuwuren.eventbus;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe; import java.util.List; /**
* 审核交易
*/
public class SimpleTradeAuditor {
private List<TradeAccountEvent> tradeEvents = Lists.newArrayList(); public SimpleTradeAuditor(EventBus eventBus) {
// 注冊, 以便获取TradeAccountEvent的通知
eventBus.register(this);
} /**
* 事件处理(用@Subscribe注解表示)
* @param tradeAccountEvent
*/
@Subscribe
public void auditTrade(TradeAccountEvent tradeAccountEvent) {
tradeEvents.add(tradeAccountEvent);
System.out.println("Received trade " + tradeAccountEvent);
}
}
TradeBuyAuditor:分类型事件消费
package com.wenniuwuren.eventbus; import java.util.List; import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe; /**
* 购买审查
* @author wenniuwuren
*
*/
public class TradeBuyAuditor {
private List<BuyEvent> buyEvents = Lists.newArrayList(); public TradeBuyAuditor(EventBus eventBus) {
eventBus.register(this);
} @Subscribe
public void auditBuy(BuyEvent buyEvent) {
buyEvents.add(buyEvent);
System.out.println("Received TradeBuyEvent " + buyEvent);
} public List<BuyEvent> getBuyEvents() {
return buyEvents;
}
}
TradeSellAuditor:
package com.wenniuwuren.eventbus; import java.util.List; import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe; /**
* 销售审查
* @author wenniuwuren
*
*/
public class TradeSellAuditor {
private List<SellEvent> sellEvents = Lists.newArrayList(); public TradeSellAuditor(EventBus eventBus) {
eventBus.register(this);
} @Subscribe
public void auditSell(SellEvent sellEvent) {
sellEvents.add(sellEvent);
System.out.println("Received SellEvent " + sellEvent);
} public List<SellEvent> getSellEvents() {
return sellEvents;
}
}
输出结果:
Processed trade forzhangsanof amount10.0typeMoney@Fri Jun 12 02:29:03 CST 2015
Received trade com.wenniuwuren.eventbus.TradeAccountEvent@7c53a9eb
----This is devil dividing line------
Processed trade forlisiof amount100.0typeSELL@Fri Jun 12 02:29:03 CST 2015
Received TradeSellEvent com.wenniuwuren.eventbus.SellEvent@14899482
---------------------
Processed trade forwangwuof amount1000.0typeBUY@Fri Jun 12 02:29:03 CST 2015
Received TradeBuyEvent com.wenniuwuren.eventbus.BuyEvent@21588809
參考资料:
《Getting Started with Google Guava》
Guava ---- EventBus事件驱动模型的更多相关文章
- guava学习--事件驱动模型
转载:http://www.cnblogs.com/whitewolf/p/4132840.html http://www.cnblogs.com/peida/p/EventBus.html 更好 ...
- Guava - EventBus(事件总线)
Guava在guava-libraries中为我们提供了事件总线EventBus库,它是事件发布订阅模式的实现,让我们能在领域驱动设计(DDD)中以事件的弱引用本质对我们的模块和领域边界很好的解耦设计 ...
- (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 本章我们讨论一个除前面的单例 ...
- Python自动化之select、greenlet和gevent和事件驱动模型初探
进程.线程和协程的区别 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度. 线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的). 协程和线程一样 ...
- 详解Spring事件驱动模型
转载自:http://jinnianshilongnian.iteye.com/blog/1902886#comments 事件驱动模型简介 事件驱动模型也就是我们常说的观察者,或者发布-订阅模型:理 ...
- 设计模式:Observer(观察者)—— Guava EventBus
本文分为三个部分: Observer(观察者) Guava EventBus详解 Guava EventBus使用示例 1. Observer(观察者) 1.1 背景 我们设计系统时, ...
- Java学习疑惑(8)----可视化编程, 对Java中事件驱动模型的理解
我们编写程序就是为了方便用户使用, 我觉得UI设计的核心就是简洁, 操作过于繁琐的程序让很大一部分用户敬而远之. 即使功能强大, 但是人们更愿意使用易于操作的软件. 近年流行起来的操作手势和逐渐趋于成 ...
- Nginx 之三:nginx服务器模块、web请求处理机制及事件驱动模型、进程功能和进程间通信
一:Nginx的模块化结构设计: 1.核心模块:指的是nginx服务器运行当中必不可少的模块,这些模块提供了最基本最核心的服务,比如权限控制.进程管理.错误日志.事件驱动.正则表达式解析等,nginx ...
- spring事件驱动模型--观察者模式在spring中的应用
spring中的事件驱动模型也叫作发布订阅模式,是观察者模式的一个典型的应用,关于观察者模式在之前的博文中总结过,http://www.cnblogs.com/fingerboy/p/5468994. ...
随机推荐
- ubuntu 12.04 配置iscsi共享及挂载iscsi共享
一.配置ubuntu 下iscsi下的target 1.配置iscsi-target: sudo apt-get install iscsi* 2.配置一个简单的iscsi target: iscsi ...
- C# Word 类库
C# Word 类库 2009-08-06 22:10 14292人阅读 评论(11) 收藏 举报 c#objectstring文档microsoftexcel using System;using ...
- 字符串匹配算法之BM算法
BM算法,全称是Boyer-Moore算法,1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法. BM算法定义了两个规则: ...
- [实现] 利用 Seq2Seq 预测句子后续字词 (Pytorch)2
最近有个任务:利用 RNN 进行句子补全,即给定一个不完整的句子,预测其后续的字词.本文使用了 Seq2Seq 模型,输入为 5 个中文字词,输出为 1 个中文字词.目录 关于RNN 语料预处理 搭建 ...
- RN code push自定义弹框
最近在弄react native的code push热更新问题.开始是用的后台默默更新配置.由于微软服务器速度问题,经常遇到用户一直在下载中问题.而用户也不知道代码需要更新才能使用新功能,影响了正常业 ...
- Java使用JNA方式调用DLL(动态链接库)(原创,装载请注明出处)
Java使用JNA调用DLL 1.准备 1.JDK环境 2.Eclipse 3.JNA包 下载JNA包: (1).JNA的Github:https://github.com/java-native-a ...
- [笔记] APIO 2018 Day1
计算折纸 computaional origami 全息算法(???) margulis napkin problem 素数里有任意长的等差数列 xor gate Σxi or gate(exact ...
- 零基础入门学习Python(31)--永久存储:腌制一缸美味的泡菜
知识点 pickle( 泡菜 ) 模块介绍: pickle模块作用是持久化的储存数据. 在Python程序运行中得到了一些字符串.列表.字典等数据,想要长久的保存下来,方便以后使用, 而不是简单的放入 ...
- [bzoj2005][Noi2010][能量采集] (容斥 or 欧拉函数)
Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后, 栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种 ...
- 【转】WEB前端调优
首先从一次完整的的请求说起:(以此为例get,www,baidu.com) 1,webbrower 发出request, 2,然后解析www.baidu.com为ip,找到ip的服务器, 3,服务器处 ...