在软件开发过程中, 难免有信息的共享或者对象间的协作。 怎样让对象间信息共享高效, 而且耦合性低。 这是一个难题。 而耦合性高将带来编码改动牵一发而动全身的连锁效应。 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事件驱动模型的更多相关文章

  1. guava学习--事件驱动模型

    转载:http://www.cnblogs.com/whitewolf/p/4132840.html   http://www.cnblogs.com/peida/p/EventBus.html 更好 ...

  2. Guava - EventBus(事件总线)

    Guava在guava-libraries中为我们提供了事件总线EventBus库,它是事件发布订阅模式的实现,让我们能在领域驱动设计(DDD)中以事件的弱引用本质对我们的模块和领域边界很好的解耦设计 ...

  3. (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 本章我们讨论一个除前面的单例 ...

  4. Python自动化之select、greenlet和gevent和事件驱动模型初探

    进程.线程和协程的区别 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度. 线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的). 协程和线程一样 ...

  5. 详解Spring事件驱动模型

    转载自:http://jinnianshilongnian.iteye.com/blog/1902886#comments 事件驱动模型简介 事件驱动模型也就是我们常说的观察者,或者发布-订阅模型:理 ...

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

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

  7. Java学习疑惑(8)----可视化编程, 对Java中事件驱动模型的理解

    我们编写程序就是为了方便用户使用, 我觉得UI设计的核心就是简洁, 操作过于繁琐的程序让很大一部分用户敬而远之. 即使功能强大, 但是人们更愿意使用易于操作的软件. 近年流行起来的操作手势和逐渐趋于成 ...

  8. Nginx 之三:nginx服务器模块、web请求处理机制及事件驱动模型、进程功能和进程间通信

    一:Nginx的模块化结构设计: 1.核心模块:指的是nginx服务器运行当中必不可少的模块,这些模块提供了最基本最核心的服务,比如权限控制.进程管理.错误日志.事件驱动.正则表达式解析等,nginx ...

  9. spring事件驱动模型--观察者模式在spring中的应用

    spring中的事件驱动模型也叫作发布订阅模式,是观察者模式的一个典型的应用,关于观察者模式在之前的博文中总结过,http://www.cnblogs.com/fingerboy/p/5468994. ...

随机推荐

  1. mac vim设置python语法高亮

    1 "显示行号  2 set nu  3   4 "设置缩进tabstop  5 set ts=4  6 set shiftwidth=4  7 set expandtab  8 ...

  2. 09CSS高级定位

    CSS高级定位 定位方式——position position:static|absolute|relative static表示为静态定位,是默认设置.  absolute表示绝对定位,与下位置属 ...

  3. android实战简易教程-链接

    http://blog.csdn.net/yayun0516/article/category/2799943

  4. getHiddenProp() 浏览器状态切换改变

    <script> function getHiddenProp() { var prefixes = ['webkit', 'moz', 'ms', 'o']; // if 'hidden ...

  5. win10 专业版 安装tornado 的步骤

    win10 专业版 安装tornado 的步骤: 1.下载tornado源码压缩包 下载网址:https://github.com/tornadoweb/tornado 若是没有github 账号可以 ...

  6. [Python3网络爬虫开发实战] 6.3-Ajax结果提取

    这里仍然以微博为例,接下来用Python来模拟这些Ajax请求,把我发过的微博爬取下来. 1. 分析请求 打开Ajax的XHR过滤器,然后一直滑动页面以加载新的微博内容.可以看到,会不断有Ajax请求 ...

  7. 22Spring基于配置文件的方式配置AOP

    直接看代码: package com.cn.spring.aop.impl; //加减乘除的接口类 public interface ArithmeticCalculator { int add(in ...

  8. Linux 搭建 squid 代理服务器 三种模式

    CentOS 6.7 squid 代理服务器 一般有两张或以上网卡,一张链接公网,访问外网资源,一张位于局域网. 代理服务器可以提供文件缓存.复制和地址过滤等服务,充分利用有限的出口带宽,加快内部主机 ...

  9. Springboot 缓存使用

    . CachingProvider . CacheManager . Cache . Entry . Expiry 1. 开启基于注解的缓存 @EnableCaching 下面列出几个核心的注解 @C ...

  10. HDU-3790最短路径问题,第十遍终于过了~

    最短路径问题                                                                   Time Limit: 2000/1000 MS (J ...