“Android設(shè)計模式”這個系列主要是對Android項目中的設(shè)計模式進行分析總結(jié),學(xué)習(xí)自《Android 源碼設(shè)計模式解析與實戰(zhàn)》,錯誤之處煩請指正~
Android設(shè)計模式系列文章:
1描函、詳解 - 單例模式
2狐粱、詳解 - Builder模式
一、 概述
1.1 定義
將一個復(fù)雜對象的構(gòu)建與表示分離開來互墓,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示蒋搜。
1.2 使用場景
相同的方法,不同的執(zhí)行順序豆挽,產(chǎn)生不同的結(jié)果
多中屬性都可以裝配到一個對象中帮哈,但是產(chǎn)生的運行結(jié)果不同
復(fù)雜的產(chǎn)品類,或者產(chǎn)品類結(jié)果會隨調(diào)用順序發(fā)生改變
初始化一個對象特別復(fù)雜,如參數(shù)特別多泳炉,且很多參數(shù)都具有默認值時
1.3 分析
Builder模式將部件和組裝過程分離嚎杨,使得構(gòu)建過程和部件都可以自由擴展,從而降低兩者耦合度刨肃。
優(yōu)點:
- 良好的封裝性自脯,使用Builder模式可以使客戶端不必知道產(chǎn)品內(nèi)部的組成細節(jié)
- Builder獨立,易于擴展
缺點:
- 會產(chǎn)生冗余的Builder對象以及組裝對象膏潮,消耗內(nèi)存
二焕参、 實現(xiàn)
2.1 示例
Builder模式非常易于上手,我們通過分析一個簡單的demo來感受Builder模式的魅力叠纷。
EventBus
框架中的 EventBusBuilder
就采用 Builder 模式實現(xiàn),我們來分析Builder模式的實現(xiàn)崇众,EventBus 3.0 源碼解析見 EventBus3.源碼解析航厚。
EventBusBuilder
是 EventBus
框架中的個性化配置類,從類名就可以看出這是一個 Builder 模式眯漩,通過Builder 對象來組裝個性化設(shè)置 EventBus
的各項參數(shù)配置麻顶,包括 是否通過Log輸出異常信息logSubscriberExceptions 等。下面看看 EventBusBuilder
的相關(guān)源碼辅肾。
public class EventBusBuilder {
private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
boolean logSubscriberExceptions = true;//是否通過Log輸出異常信息
boolean logNoSubscriberMessages = true;//是否通過Log輸出發(fā)送事件無訂閱者信息
boolean sendSubscriberExceptionEvent = true;//是否將內(nèi)部異常信息通過SubscriberExceptionEvent發(fā)送出去
boolean sendNoSubscriberEvent = true;//是否將無訂閱者的時間通過NoSubscriberEvent發(fā)送出去
boolean throwSubscriberException;//是否將內(nèi)部異常信息通過EventBusException拋出
boolean eventInheritance = true;//發(fā)送事件是否支持調(diào)用所有父類及實現(xiàn)的接口
boolean ignoreGeneratedIndex;//是否忽略生成被觀察者訂閱的方法(通過反射)
boolean strictMethodVerification;//是否開啟嚴格的方法驗證,(public,只有一個參數(shù),不為static及abstract),非法則均拋出異常
ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;//發(fā)送事件的線程池
List<Class<?>> skipMethodVerificationForClasses;//對類忽略方法校驗矫钓,目前未實現(xiàn)
List<SubscriberInfoIndex> subscriberInfoIndexes;//通過annotation preprocessor生成的訂閱者方法list
EventBusBuilder() {
}
/**
* 設(shè)置 logSubscriberExceptions,默認為true
* @param logSubscriberExceptions
* @return
*/
public EventBusBuilder logSubscriberExceptions(boolean logSubscriberExceptions) {
this.logSubscriberExceptions = logSubscriberExceptions;
return this;
}
/**
* 設(shè)置 logNoSubscriberMessages,默認為 true
* @param logNoSubscriberMessages
* @return
*/
public EventBusBuilder logNoSubscriberMessages(boolean logNoSubscriberMessages) {
this.logNoSubscriberMessages = logNoSubscriberMessages;
return this;
}
/**
* 設(shè)置 sendSubscriberExceptionEvent,默認為 true
* @param sendSubscriberExceptionEvent
* @return
*/
public EventBusBuilder sendSubscriberExceptionEvent(boolean sendSubscriberExceptionEvent) {
this.sendSubscriberExceptionEvent = sendSubscriberExceptionEvent;
return this;
}
/**
* 設(shè)置 sendNoSubscriberEvent,默認為 true
* @param sendNoSubscriberEvent
* @return
*/
public EventBusBuilder sendNoSubscriberEvent(boolean sendNoSubscriberEvent) {
this.sendNoSubscriberEvent = sendNoSubscriberEvent;
return this;
}
/**
* 設(shè)置 throwSubscriberException,默認為 false
* @param throwSubscriberException
* @return
*/
public EventBusBuilder throwSubscriberException(boolean throwSubscriberException) {
this.throwSubscriberException = throwSubscriberException;
return this;
}
/**
* 設(shè)置 eventInheritance,默認為 true
* @param eventInheritance
* @return
*/
public EventBusBuilder eventInheritance(boolean eventInheritance) {
this.eventInheritance = eventInheritance;
return this;
}
/**
* 設(shè)置 executorService
* @param executorService
* @return
*/
public EventBusBuilder executorService(ExecutorService executorService) {
this.executorService = executorService;
return this;
}
/**
* 設(shè)置 skipMethodVerificationForClasses
* @param clazz
* @return
*/
public EventBusBuilder skipMethodVerificationFor(Class<?> clazz) {
if (skipMethodVerificationForClasses == null) {
skipMethodVerificationForClasses = new ArrayList<>();
}
skipMethodVerificationForClasses.add(clazz);
return this;
}
/**
* 設(shè)置 ignoreGeneratedIndex
* @param ignoreGeneratedIndex
* @return
*/
public EventBusBuilder ignoreGeneratedIndex(boolean ignoreGeneratedIndex) {
this.ignoreGeneratedIndex = ignoreGeneratedIndex;
return this;
}
/**
* 設(shè)置 strictMethodVerification
* @param strictMethodVerification
* @return
*/
public EventBusBuilder strictMethodVerification(boolean strictMethodVerification) {
this.strictMethodVerification = strictMethodVerification;
return this;
}
/**
* 設(shè)置 subscriberInfoIndexes
* @param index
* @return
*/
public EventBusBuilder addIndex(SubscriberInfoIndex index) {
if(subscriberInfoIndexes == null) {
subscriberInfoIndexes = new ArrayList<>();
}
subscriberInfoIndexes.add(index);
return this;
}
/**
* 實現(xiàn)修改 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 方式實現(xiàn) EventBus 初始化
* @return
*/
public EventBus build() {
return new EventBus(this);
}
}
上述代碼中盈电,EventBusBuilder
類可以設(shè)置 EventBus
中的 * logSubscriberExceptions匆帚、logNoSubscriberMessages旁钧、sendSubscriberExceptionEvent* 等參數(shù),這些參數(shù)統(tǒng)一存儲在 EventBusBuilder
中歪今。在調(diào)用 EventBusBuilder
類的 build()
函數(shù)時會創(chuàng)建 EventBus
,并且將各項配置用于到 EventBus
中去嫉晶。
EventBusBuilder
采用 Builder 模式主要是初始化 EventBus
配置項參數(shù)復(fù)雜田篇,并且很多參數(shù)具有默認值,在使用時可能只需要對部分參數(shù)進行修改泊柬,故采用 Builder 模式方便修改初始化。
2.2 小結(jié)
通過 2.1節(jié) 可以看出 Builder 模式使用非常方便状答,并且對于多參數(shù)屬性初始化來說刀崖,極大的簡化了工作。
在項目中合理的加入 Builder 模式吧~
三译断、小結(jié)
Builder 模式在 Android 開發(fā)中較為常用或悲,通常作為配置類的構(gòu)造器將配置的構(gòu)建和表示分離開來,同時也實現(xiàn)了將配置類從目標類中抽離出來巡语,避免了過多的 setter
方法。
Builder 模式比較常見的實現(xiàn)方式是通過調(diào)用鏈實現(xiàn)荤堪,這樣使得代碼簡單易懂。
本文對 Builder模式 的分析到此就結(jié)束了澄阳,部分內(nèi)容學(xué)習(xí)自 《Android源碼設(shè)計模式 解析與實戰(zhàn)》。
附: