使用函数式实现观察者模式模式

栏目: 后端 · 发布时间: 5年前

内容简介:观察者模式肯定是最常见和最广泛使用的模式之一。其目的是允许在某个事件发生时通知一个或多个对象并相应地采取行动。这种模式的主要抽象是Listener接口:当on对象想要在事件发生时得到通知,或者要监听事件时,它只需实现此接口并在onEvent()方法的主体中编码它如何对事件的到达作出反应。对应的是一个Observable对象,或者换句话说,一个对象通过在相关事件发生时向它们发送事件来通知其注册的侦听器。在引入lambdas之前,在这个Observable上注册Listener的两种典型方法是通过匿名内部类:

观察者模式肯定是最常见和最广泛使用的模式之一。其目的是允许在某个事件发生时通知一个或多个对象并相应地采取行动。这种模式的主要抽象是Listener接口:

<b>interface</b> Listener {
    <b>void</b> onEvent(Object event);
}

当on对象想要在事件发生时得到通知,或者要监听事件时,它只需实现此接口并在onEvent()方法的主体中编码它如何对事件的到达作出反应。对应的是一个Observable对象,或者换句话说,一个对象通过在相关事件发生时向它们发送事件来通知其注册的侦听器。

<b>public</b> <b>class</b> Observable {
    <b>private</b> <b>final</b> Map<Object, Listener> listeners = <b>new</b> ConcurrentHashMap<>();
 
    <b>public</b> <b>void</b> register(Object key, Listener listener) {
        listeners.put(key, listener);
    }
 
    <b>public</b> <b>void</b> unregister(Object key) {
        listeners.remove(key);
    }
 
    <b>public</b> <b>void</b> sendEvent(Object event) {
        <b>for</b> (Listener listener : listeners.values()) {
            listener.onEvent( event );
        }
    }
}

在引入lambdas之前,在这个Observable上注册Listener的两种典型方法是通过匿名内部类:

<b>public</b> <b>class</b> Observer1 {
    Observer1(Observable observable) {
        observable.register( <b>this</b>, <b>new</b> Listener() {
            @Override
            <b>public</b> <b>void</b> onEvent( Object event ) {
                System.out.println(event);
            }
        } );
    }
}

或使您的对象直接实现Listener接口。

<b>public</b> <b>class</b> Observer2 implements Listener {
    Observer2(Observable observable) {
        observable.register( <b>this</b>, <b>this</b> );
    }
    @Override
    <b>public</b> <b>void</b> onEvent( Object event ) {
        System.out.println(event);
    }
}

这两个观察者都可以以相同的方式使用,当Observable发送一个事件时,它将被广播到:

Observable observable = <b>new</b> Observable();
<b>new</b> Observer1( observable );
<b>new</b> Observer2( observable );
observable.sendEvent( <font>"Hello World!"</font><font> );
</font>

然而,这两个解决方案再一次揭示了GoF模式最大部分的常见问题:它们必须将动词以及事件到达时要采取的行动转换为名词、类别、匿名或不包装这些行为。为了利用 Java 8的新功能特性,首先要注意的是我们上面定义的Listener接口在语义上等同于Consumer:

<b>public</b> <b>class</b> Observable {
    <b>private</b> <b>final</b> Map<Object, Consumer<Object>> listeners = <b>new</b> ConcurrentHashMap<>();
 
    <b>public</b> <b>void</b> register(Object key, Consumer<Object> listener) {
        listeners.put(key, listener);
    }
 
    <b>public</b> <b>void</b> unregister(Object key) {
        listeners.remove(key);
    }
 
    <b>public</b> <b>void</b> sendEvent(Object event) {
        listeners.values().forEach( listener -> listener.accept( event ) );
    }
}

此外,不再需要使用特定类实现Listener,并且可以使用lambda表达式对事件到达的反应进行编码,或者在这种情况下也使用更简洁的方法引用进行编码。

Observable observable = <b>new</b> Observable();
observable.register( <font>"key1"</font><font>, e -> System.out.println(e) );
observable.register( </font><font>"key2"</font><font>, System.out::println );
observable.sendEvent( </font><font>"Hello World!"</font><font> );
</font>

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Mashups Web 2.0开发技术—— 基于Amazon.com

Mashups Web 2.0开发技术—— 基于Amazon.com

萨拉汉 / 吴宏泉 / 清华大学 / 2008-1 / 48.00元

《MashupsWeb2.0开发技术(基于Amazon.Com) 》介绍了mashup的底层技术,并且第一次展示了如何创建mashup的应用程序。Amazon.com与Web服务强势结合,拓展了Internet的应用范围,使得开发人员可以把Amazon的数据和其他的可利用资源自由地结合起来创建功能丰富的全新应用程序,这种应用程序叫做mashup。 《MashupsWeb2.0开发技术(基于A......一起来看看 《Mashups Web 2.0开发技术—— 基于Amazon.com》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具