上一篇 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<Class<?>, CopyOnWriteArrayList<Subscription>>();
typesBySubscriber = new HashMap<Object, List<Class<?>>>();
stickyEvents = new ConcurrentHashMap<Class<?>, 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<Class<?>> 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
网友评论