观察者模式

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

内容简介:观察者模式中的角色可以分为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

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

查看所有标签

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

Learning JavaScript

Learning JavaScript

Shelley Powers / Oreilly & Associates Inc / 2006-10-17 / $29.99

As web browsers have become more capable and standards compliant, JavaScript has grown in prominence. JavaScript lets designers add sparkle and life to web pages, while more complex JavaScript has led......一起来看看 《Learning JavaScript》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具