• 2013-04-18

    你应该更新的Java知识之Observer

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/dreamhead-logs/231594181.html

    作为一个Java程序员,不熟悉设计模式简直不好意思和人打招呼,而Observer模式可以说是位列最常用的设计模式之列,虽然有时候在具体代码里,它不一定叫这个名字,比如改头换面叫个Listener,但模式就是这个模式。

    手工实现一个Observer也不是多复杂的一件事,只是因为这个设计模式实在太常用了,Java就把它放到了JDK里面:ObservableObserver,从JDK 1.0里,它们就一直在那里。从某种程度上说,它简化了Observer模式的开发,至少我们不用再手工维护自己的Observer列表了。

    不过,如前所述,JDK里的Observer从1.0就在那里了,直到Java 7,它都没有什么改变,就连通知的参数还是Object类型。要知道,Java 5就已经泛型了。Java 5是一次大规模的语法调整,许多程序库从那开始重新设计了API,使其更简洁易用。当然,那些不做应对的程序库,多半也就过时了。这也就是这里要讨论知识更新的原因所在。

    今天,对于普通的应用,如果要使用Observer模式该如何做呢?答案是GuavaEventBus。如你所见,它的名字并没有直接告诉你它是一个Observer,但这有什么关系呢,Listener不也是这样。

    首先,我们声明一个Observer:

    public class EventObserver {
     @Subscribe public void onMessage(Message message) {
       ...
     }
    }

    你会发现,这个类并没有继承任何接口,只是在用来响应通知的方法上声明了一个@Subscribe。

    使用EventBus很简单,先声明一个

      EventBus eventBus = new EventBus();

    然后,把我们写好的Observer注册进去:

      eventBus.register(new EventObserver());

    当要通知Observer时,我们只要这样即可:

      eventBus.post(message);

    这里,我们并没有告诉EventBus,我们要处理的是一个Message类型,只是在EventObserver的onMessage方法的接口声明上使用了这个类型而已。但是,当我们把消息发送出去的时候,它会根据类型进行匹配,保证我们的消息正确地发送到对应的地方。

    相比于JDK原有的实现,这个实现会更简单。EventObserver不再需要存在一个继承体系中,而继承总是一种枷锁,把我们套牢在一个体系之中:

    • 我们不必遵循一个特定的名字,比如Observer的update,而这里的名字onMessage是我们自己起的。
    • 我们不必遵循特定的类型,比如update方法中作为被观察对象Observable和作为参数的Object,而是根据我们自己的需求选择的类型。

    这种变换让静态类型的Java语言,有了一些动态类型的特质,也让程序更加灵活。这种灵活性多半要归功于Annotation,它在很大程度上影响了Java的程序设计风格。

    除了标准的EventBus,Guava还提供了另外一个AsyncEventBus,从名字就可以看出,这是一个异步的EventBus,也就是说,消息扔给它之后,会立即返回,至于Observer什么时候处理,那就是它的事情了。

    如果你想更多地了解EventBus,那Guava的官方文档是个不错的去处。

    分享到:

    历史上的今天:

    Rails初印象 2008-04-18
    原始武器 2004-04-18
    引用地址:

    评论

  • 有些字在评论中不能敲,真的很费劲
  • 之前看过别人介绍spring见听模式,不知道两者有什么区别吗?
  • 已经不能评论了吗?
  • 这意味着JDK1.0里的Observer过时了,很好的介绍。期待更多Java知识更新。
    回复wintys说:
    多谢期待,我也努力更新更多。
    2013-04-18 17:54:11