使用Google的Guava工具EventBus-观察者模式

EventBus是Google.Guava提供的消息发布-订阅类库,它实现了观察者设计模式,消息通知负责人通过EventBus去注册/注销观察者,最后由消息通知负责人给观察者发布消息。

首先使用 maven 依赖:

[java]  view plain  copy
  1.   
  2.           
  3.             com.google.guava  
  4.             guava  
  5.             19.0  
  6.           

示例代码:

EventBusCenter.java

[java]  view plain  copy
  1. package com.lance.google.event.bus;  
  2.   
  3. import com.google.common.eventbus.EventBus;  
  4.   
  5. /** 
  6.  * Created by zhangzh on 2017/1/10. 
  7.  */  
  8. public class EventBusCenter {  
  9.   
  10.     private static EventBus eventBus = new EventBus();  
  11.   
  12.     private EventBusCenter() {  
  13.   
  14.     }  
  15.   
  16.     public static EventBus getInstance() {  
  17.         return eventBus;  
  18.     }  
  19.   
  20.     public static void register(Object obj) {  
  21.         eventBus.register(obj);  
  22.     }  
  23.   
  24.     public static void unregister(Object obj) {  
  25.         eventBus.unregister(obj);  
  26.     }  
  27.   
  28.     public static void post(Object obj) {  
  29.         eventBus.post(obj);  
  30.     }  
  31.   
  32.   
  33. }  

观察者一

[java]  view plain  copy
  1. package com.lance.google.event.bus;  
  2.   
  3. import com.google.common.eventbus.Subscribe;  
  4.   
  5. /** 
  6.  * Created by zhangzh on 2017/1/10. 
  7.  */  
  8. public class DataObserver1 {  
  9.   
  10.     /** 
  11.      * 只有通过@Subscribe注解的方法才会被注册进EventBus 
  12.      * 而且方法有且只能有1个参数 
  13.      * 
  14.      * @param msg 
  15.      */  
  16.     @Subscribe  
  17.     public void func(String msg) {  
  18.         System.out.println("String msg: " + msg);  
  19.     }  
  20.   
  21. }  

观察者二

[java]  view plain  copy
  1. package com.lance.google.event.bus;  
  2.   
  3. import com.google.common.eventbus.Subscribe;  
  4.   
  5. /** 
  6.  * Created by zhangzh on 2017/1/10. 
  7.  */  
  8. public class DataObserver2 {  
  9.     /** 
  10.      * post() 不支持自动装箱功能,只能使用Integer,不能使用int,否则handlersByType的Class会是int而不是Intege 
  11.      * 而传入的int msg参数在post(int msg)的时候会被包装成Integer,导致无法匹配到 
  12.      */  
  13.     @Subscribe  
  14.     public void func(Integer msg) {  
  15.         System.out.println("Integer msg: " + msg);  
  16.     }  
  17. }  

代码测试

Test.java

[java]  view plain  copy
  1. package com.lance.google.event.bus;  
  2.   
  3. /** 
  4.  * Created by zhangzh on 2017/1/10. 
  5.  */  
  6. public class Test {  
  7.   
  8.     public static void main(String[] args) throws InterruptedException {  
  9.   
  10.         DataObserver1 observer1 = new DataObserver1();  
  11.         DataObserver2 observer2 = new DataObserver2();  
  12.   
  13.         EventBusCenter.register(observer1);  
  14.         EventBusCenter.register(observer2);  
  15.   
  16.         System.out.println("============   start  ====================");  
  17.   
  18.         // 只有注册的参数类型为String的方法会被调用  
  19.         EventBusCenter.post("post string method");  
  20.         EventBusCenter.post(123);  
  21.   
  22.         System.out.println("============ after unregister ============");  
  23.         // 注销observer2  
  24.         EventBusCenter.unregister(observer2);  
  25.         EventBusCenter.post("post string method");  
  26.         EventBusCenter.post(123);  
  27.   
  28.         System.out.println("============    end           =============");  
  29.     }  
  30. }  

输出结果:

[java]  view plain  copy
  1. ============   start  ====================  
  2. String msg: post string method  
  3. Integer msg: 123  
  4. ============ after unregister ============  
  5. String msg: post string method  
  6. ============    end           =============  

看使用起来简单吧!

EventBus的使用注意问题:
1.代码可读性很差,项目中使用的时候,从post的地方,查询handle使用,都是使用ide的搜索服务,问题很难定位,不如普通的接口调用方便查询;
2.由于EventBus是将消息队列放入到内存中的,listener消费这个消息队列,故系统重启之后,保存或者堆积在队列中的消息丢失。

你可能感兴趣的:(Java设计模式)