观察者模式

栏目: IOS · Android · 发布时间: 5年前

内容简介:观察者模式中的角色可以分为Subject和Observer,它们分别为被观察者和观察者,观察者观察被观察者的状态变更。google的guava中提供了EventBus功能,EventBus可以实现观察者模式,下面是一个简单的例子我们也可以自己实现一个EventBus,虽然在效率上没办法和google的实现相比,但是基本原理都是一样的。首先我们创建一个用于标记方法是否需要实现订阅的注解

观察者模式中的角色可以分为Subject和Observer,它们分别为被观察者和观察者,观察者观察被观察者的状态变更。google的guava中提供了EventBus功能,EventBus可以实现观察者模式,下面是一个简单的例子

import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

public class TestEventBus {

    public static void main(String[] args) {
        EventBus eventBus = new EventBus("test");
        // 注册一个listener
        eventBus.register(new Listener());
        // 遍历被注册的对象以及其方法,调用符合要求的方法
        eventBus.post(new Event("hello, world"));
    }

}

class Event {
    public String message;

    Event(String message) {
        this.message = message;
    }
}

class Listener {
    @Subscribe
    public void listen(Event event) {
        System.out.println(event.message);
    }
}

我们也可以自己实现一个EventBus,虽然在效率上没办法和google的实现相比,但是基本原理都是一样的。

首先我们创建一个用于标记方法是否需要实现订阅的注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Subscribe {
}

随后创建EventBus的核心类,其主要功能是添加或移除listener,以及根据传入的参数对符合要求的方法进行调用

public class EventBus {

    private Set<Object> listeners = new HashSet<>();

    public void register(Object listener) {
        listeners.add(listener);
    }

    public void unregister(Object listener) {
        listeners.remove(listener);
    }

    // 1. 遍历所有的listener对象;
    // 2. 遍历所有的listener对象的方法;
    // 3. 判断该方法是否添加了订阅注解,方法的参数个数和参数类型是否符合调用方的参数要求;
    // 4. 如果一切条件都符合,执行该方法;
    public void post(Object event) {
        for (Object listener : listeners) {
            Method[] methods = listener.getClass().getDeclaredMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(Subscribe.class)) {
                    Class[] parameterTypes = method.getParameterTypes();
                    if (parameterTypes.length == 1 && parameterTypes[0] == event.getClass()) {
                        try {
                            // 调用方法
                            method.invoke(listener, event);
                        } catch (IllegalAccessException | InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

}

最后我们对上面的实现进行测试

public class Test {

    public static void main(String[] args) {
        EventBus eventBus = new EventBus();
        eventBus.register(new Listener());
        eventBus.post("Mike");
    }

}

class Listener {
    @Subscribe
    public void say(String name) {
        System.out.println("hello, " + name);
    }
}

测试代码打印出了如下结果

hello, Mike

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

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

思想的未来

思想的未来

(美)劳伦斯﹒莱斯格 / 李旭 / 中信出版社 / 2004-10 / 29.00元

因特网革命已到来,一些人说它已经过去,革命缘何而来?又缘何而去呢? 劳伦斯·莱斯格对因特网革命中为何会出现一种反革命的破坏性力量及后果做出了解释。创作之所以繁荣,是因为因特网保护了创新的公共资源。是因为因特网保护了创新的公共资源。因特网的独特设计营造出一个中立的平台。最广大范围的作者们可在此平台上进行试验。围绕此平台的法律架构对这一自由空间给予了保护,以使文化和信息——我们这个时代的......一起来看看 《思想的未来》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

html转js在线工具
html转js在线工具

html转js在线工具