EventBus设计模式剖析(二)建造者模式

上一篇 EventBus设计模式剖析(一)单例模式

下一篇 EventBus设计模式剖析(三)观察者模式

EventBus:

由开源组织greenrobot开发的事件发布-订阅总线库。

设计模式:

软件开发中问题的解决套路。

建造者模式简介

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式将一个复杂对象的创建过程封装起来,允许对象通过多个步骤来创建,并且可以改变过程。尤其是在对象特别复杂,内部参数及其多的时候,建造者模式就能发挥出它的优势。
若源代码中有Builder这个词,大概率使用了建造者模式。

EventBusBulider类中的建造者模式

上一篇文章讲解了EventBus单例模式的构造方法,也是最经常使用的模式。现在我们来讨论一下建造者模式的构造方法。使用建造者模式,我们可以自行调整EventBus的配置,使之满足满足我们的特定需求。

public class EventBus {

    static volatile EventBus defaultInstance;  // volatile关键字保证defaultInstance所有线程共享
    
    private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
    
    // 对于应用程序,使用一个所有线程都能使用EventBus实例,单例。
    // 用的是Double Check Lock实现单例
    public static EventBus getDefault() {
        if (defaultInstance == null) {
            synchronized (EventBus.class) {
                if (defaultInstance == null) {
                    defaultInstance = new EventBus();
                }
            }
        }
        return defaultInstance;
    }
     
    //  创建一个新的EventBus实例,每个实例都是一个单独的作用域,在该作用域中传递事件   
    //  若想要一个中心总线,可以考虑使用getDefault()返回单例
    public EventBus() {
        this(DEFAULT_BUILDER);
    }
    // 建造者模式创建EventBus
    EventBus(EventBusBuilder builder) {
        subscriptionsByEventType = new HashMap, CopyOnWriteArrayList>();
        typesBySubscriber = new HashMap>>();
        stickyEvents = new ConcurrentHashMap, Object>();
        mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
        backgroundPoster = new BackgroundPoster(this);
        asyncPoster = new AsyncPoster(this);
        subscriberMethodFinder = new SubscriberMethodFinder(builder.skipMethodVerificationForClasses);
        logSubscriberExceptions = builder.logSubscriberExceptions;
        logNoSubscriberMessages = builder.logNoSubscriberMessages;
        sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
        sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
        throwSubscriberException = builder.throwSubscriberException;
        eventInheritance = builder.eventInheritance;
        executorService = builder.executorService;
    }

}

EventBusBuilder类部分源码如下:

// 使用自定义参数创建EventBus实例,也可以创建默认的EventBus实例。
// 使用EventBus的builder()创建。
public class EventBusBuilder {
    private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();

    boolean logSubscriberExceptions = true; // 是否打印订阅者异常信息,默认开启
    boolean logNoSubscriberMessages = true; // 某个事件没有订阅者时,是否打印信息,默认开启
    boolean sendSubscriberExceptionEvent = true; // 出现订阅者异常时,是否发送异常事件,默认开启
    boolean sendNoSubscriberEvent = true; // 某个事件没有订阅者时,是否发送无订阅者的事件,默认开启
    boolean throwSubscriberException; // 是否抛出订阅者异常信息,默认关闭
    boolean eventInheritance = true; // 事件是否可以继承形式订阅,默认开启
    ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE; // 一个线程池,表述异步执行的机制,并且可以让任务在后台执行
    List> skipMethodVerificationForClasses; // 跳过为订阅者类里面的方法进行校验

    EventBusBuilder() {}// 构造函数

    public EventBusBuilder logSubscriberExceptions(boolean logSubscriberExceptions) {}

    public EventBusBuilder logNoSubscriberMessages(boolean logNoSubscriberMessages) {}

    public EventBusBuilder sendSubscriberExceptionEvent(boolean sendSubscriberExceptionEvent) {}

    public EventBusBuilder sendNoSubscriberEvent(boolean sendNoSubscriberEvent) {}

    // 如果订阅者引发异常,则失败(默认值:false) 
    public EventBusBuilder throwSubscriberException(boolean throwSubscriberException) {}

    // 默认情况下,EventBus考虑事件类层次结构(将通知订阅者的父类)。
    public EventBusBuilder eventInheritance(boolean eventInheritance) {}
     
    // 用于异步和后台事件传递的事件总线提供自定义线程池。
    public EventBusBuilder executorService(ExecutorService executorService) {}

    // 跳过为订阅者类里面的方法进行校验,校验包括注解信息、修饰符是否是public且非static\final的,默认为空
    public EventBusBuilder skipMethodVerificationFor(Class clazz) {}

    // 建造这个配置的EventBus,但是依然保证单例
    public EventBus installDefaultEventBus() {
        synchronized (EventBus.class) {
            if (EventBus.defaultInstance != null) {
                throw new EventBusException("Default instance already exists." +
                        " It may be only set once before it's used the first time to ensure consistent behavior.");
            }
            EventBus.defaultInstance = build();
            return EventBus.defaultInstance;
        }
    }

    // 建造这个配置的EventBus,但是不保证单例
    public EventBus build() {
        return new EventBus(this);
    }

}

比如我们想定义一个不打印订阅者异常信息,不打印没有订阅者的事件,事件不可以继承形式订阅得单例EventBus,注意用的方法是installDefaultEventBus()。

        EventBus.builder().logNoSubscriberMessages(false)
                .logSubscriberExceptions(false).eventInheritance(false)
                .installDefaultEventBus();

我们想定义一个不打印订阅者异常信息,不打印没有订阅者的事件,事件不可以继承形式订阅得非单例,可作用于特定域的EventBus,注意用的方法是build()。

        EventBus.builder().logNoSubscriberMessages(false)
                .logSubscriberExceptions(false).eventInheritance(false)...
                .build();

基于建造模式构建的其他代码

1、OkHttp框架中的OkHttpClient,Request,Response类
2、Android源码中的AlertDialog类

参考文献

1、设计模式|菜鸟教程:https://www.runoob.com/design-pattern/design-pattern-tutorial.html
2、《Android源码设计模式解析与实战》何红辉,关爱民著
3、蕉下孤客:https://www.jianshu.com/p/1b68ace4600a
4、野生的安卓兽:https://www.jianshu.com/nb/10598547

上一篇 EventBus设计模式剖析(一)单例模式

下一篇 EventBus设计模式剖析(三)观察者模式

All is well.

你可能感兴趣的:(EventBus设计模式剖析(二)建造者模式)