“Android设计模式”这个系列主要是对Android项目中的设计模式进行分析总结,学习自《Android 源码设计模式解析与实战》,错误之处烦请指正~
Android设计模式系列文章:
一、 概述
1.1 定义
将一个复杂对象的构建与表示分离开来,使得同样的构建过程可以创建不同的表示。
1.2 使用场景
相同的方法,不同的执行顺序,产生不同的结果
多中属性都可以装配到一个对象中,但是产生的运行结果不同
复杂的产品类,或者产品类结果会随调用顺序发生改变
初始化一个对象特别复杂,如参数特别多,且很多参数都具有默认值时
1.3 分析
Builder模式将部件和组装过程分离,使得构建过程和部件都可以自由扩展,从而降低两者耦合度。
优点:
- 良好的封装性,使用Builder模式可以使客户端不必知道产品内部的组成细节
- Builder独立,易于扩展
缺点:
- 会产生冗余的Builder对象以及组装对象,消耗内存
二、 实现
2.1 示例
Builder模式非常易于上手,我们通过分析一个简单的demo来感受Builder模式的魅力。
EventBus
框架中的 EventBusBuilder
就采用 Builder 模式实现,我们来分析Builder模式的实现,EventBus 3.0 源码解析见 EventBus3.源码解析。
EventBusBuilder
是 EventBus
框架中的个性化配置类,从类名就可以看出这是一个 Builder 模式,通过Builder 对象来组装个性化设置 EventBus
的各项参数配置,包括 是否通过Log输出异常信息logSubscriberExceptions 等。下面看看 EventBusBuilder
的相关源码。
public class EventBusBuilder {
private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
boolean logSubscriberExceptions = true;//是否通过Log输出异常信息
boolean logNoSubscriberMessages = true;//是否通过Log输出发送事件无订阅者信息
boolean sendSubscriberExceptionEvent = true;//是否将内部异常信息通过SubscriberExceptionEvent发送出去
boolean sendNoSubscriberEvent = true;//是否将无订阅者的时间通过NoSubscriberEvent发送出去
boolean throwSubscriberException;//是否将内部异常信息通过EventBusException抛出
boolean eventInheritance = true;//发送事件是否支持调用所有父类及实现的接口
boolean ignoreGeneratedIndex;//是否忽略生成被观察者订阅的方法(通过反射)
boolean strictMethodVerification;//是否开启严格的方法验证,(public,只有一个参数,不为static及abstract),非法则均抛出异常
ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;//发送事件的线程池
List<Class<?>> skipMethodVerificationForClasses;//对类忽略方法校验,目前未实现
List<SubscriberInfoIndex> subscriberInfoIndexes;//通过annotation preprocessor生成的订阅者方法list
EventBusBuilder() {
}
/**
* 设置 logSubscriberExceptions,默认为true
* @param logSubscriberExceptions
* @return
*/
public EventBusBuilder logSubscriberExceptions(boolean logSubscriberExceptions) {
this.logSubscriberExceptions = logSubscriberExceptions;
return this;
}
/**
* 设置 logNoSubscriberMessages,默认为 true
* @param logNoSubscriberMessages
* @return
*/
public EventBusBuilder logNoSubscriberMessages(boolean logNoSubscriberMessages) {
this.logNoSubscriberMessages = logNoSubscriberMessages;
return this;
}
/**
* 设置 sendSubscriberExceptionEvent,默认为 true
* @param sendSubscriberExceptionEvent
* @return
*/
public EventBusBuilder sendSubscriberExceptionEvent(boolean sendSubscriberExceptionEvent) {
this.sendSubscriberExceptionEvent = sendSubscriberExceptionEvent;
return this;
}
/**
* 设置 sendNoSubscriberEvent,默认为 true
* @param sendNoSubscriberEvent
* @return
*/
public EventBusBuilder sendNoSubscriberEvent(boolean sendNoSubscriberEvent) {
this.sendNoSubscriberEvent = sendNoSubscriberEvent;
return this;
}
/**
* 设置 throwSubscriberException,默认为 false
* @param throwSubscriberException
* @return
*/
public EventBusBuilder throwSubscriberException(boolean throwSubscriberException) {
this.throwSubscriberException = throwSubscriberException;
return this;
}
/**
* 设置 eventInheritance,默认为 true
* @param eventInheritance
* @return
*/
public EventBusBuilder eventInheritance(boolean eventInheritance) {
this.eventInheritance = eventInheritance;
return this;
}
/**
* 设置 executorService
* @param executorService
* @return
*/
public EventBusBuilder executorService(ExecutorService executorService) {
this.executorService = executorService;
return this;
}
/**
* 设置 skipMethodVerificationForClasses
* @param clazz
* @return
*/
public EventBusBuilder skipMethodVerificationFor(Class<?> clazz) {
if (skipMethodVerificationForClasses == null) {
skipMethodVerificationForClasses = new ArrayList<>();
}
skipMethodVerificationForClasses.add(clazz);
return this;
}
/**
* 设置 ignoreGeneratedIndex
* @param ignoreGeneratedIndex
* @return
*/
public EventBusBuilder ignoreGeneratedIndex(boolean ignoreGeneratedIndex) {
this.ignoreGeneratedIndex = ignoreGeneratedIndex;
return this;
}
/**
* 设置 strictMethodVerification
* @param strictMethodVerification
* @return
*/
public EventBusBuilder strictMethodVerification(boolean strictMethodVerification) {
this.strictMethodVerification = strictMethodVerification;
return this;
}
/**
* 设置 subscriberInfoIndexes
* @param index
* @return
*/
public EventBusBuilder addIndex(SubscriberInfoIndex index) {
if(subscriberInfoIndexes == null) {
subscriberInfoIndexes = new ArrayList<>();
}
subscriberInfoIndexes.add(index);
return this;
}
/**
* 实现修改 EventBus 默认 EventBusBuilder(EventBus.defaultInstance)
* @return
*/
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;
}
}
/**
* 通过 build 方式实现 EventBus 初始化
* @return
*/
public EventBus build() {
return new EventBus(this);
}
}
上述代码中,EventBusBuilder
类可以设置 EventBus
中的 * logSubscriberExceptions、logNoSubscriberMessages、sendSubscriberExceptionEvent* 等参数,这些参数统一存储在 EventBusBuilder
中。在调用 EventBusBuilder
类的 build()
函数时会创建 EventBus
,并且将各项配置用于到 EventBus
中去。
EventBusBuilder
采用 Builder 模式主要是初始化 EventBus
配置项参数复杂,并且很多参数具有默认值,在使用时可能只需要对部分参数进行修改,故采用 Builder 模式方便修改初始化。
2.2 小结
通过 2.1节 可以看出 Builder 模式使用非常方便,并且对于多参数属性初始化来说,极大的简化了工作。
在项目中合理的加入 Builder 模式吧~
三、小结
Builder 模式在 Android 开发中较为常用,通常作为配置类的构造器将配置的构建和表示分离开来,同时也实现了将配置类从目标类中抽离出来,避免了过多的 setter
方法。
Builder 模式比较常见的实现方式是通过调用链实现,这样使得代码简单易懂。
本文对 Builder模式 的分析到此就结束了,部分内容学习自 《Android源码设计模式 解析与实战》。
附: