從Android原始碼來看“Builder模式”
本文主要解釋什麼是Builder模式,及其作用。然後結合 Android 原始碼來看一下Builder模式的實現。
什麼是Builder模式
Build 是構建、建造的意思,Builder 模式又稱建造者模式。
Builder模式中包括兩個核心元素:產品和建造者。這兩者可以比作房屋和磚瓦匠。在建造房屋這個過程中,如果建築公司直接操作房子,除了要對牆壁的顏色、地板的材質、屋頂的形狀作出選擇外,還要注意建造房屋時的順序:先打地基、再壘牆壁、最後封頂等等。記住構建房屋的每一步及其順序,這對建築公司來說是十分麻煩的。而如果建築公司引入磚瓦匠的角色,將構建房子的流程等工作交給磚瓦匠,自己只需告訴磚瓦匠:“我要木質地板、白色的牆壁、紅色屋頂”即可,構建房屋所涉及的複雜流程就無需關心。另外,當建造房屋的流程發生變化時,建築公司仍然只需告訴磚瓦匠:“我要木質地板、白色的牆壁、紅色屋頂”,而不需作出任何改變。
由上邊的比喻可以看出,Builder模式是將房子本身的設計、表示和房子的構建進行分離。不使用此模式,開發者不僅需要關注一個產品的表示,比如AlertDialog的title、button等介面元素,還要關注構建產品的步驟。更加重要的是,如果建造房屋的流程發生變化,不能夠再按照以前構建產品的方式建立產品的話,開發者就不得不修改程式碼來適配新的構建流程。Builder模式可以解決這些問題,為產品增加Builder角色,將構建過程交給Builder實現,開發者只需關心產品屬性的設定即可。
就像建築公司僱傭磚瓦匠需要發工資一樣,使用Builder模式的缺點便是需要為增加的Builder物件分配記憶體。
原始碼中的Builder模式
在Android原始碼中,比較常見的是AlertDialog的使用。程式碼如下:
val builder = AlertDialog.Builder(this)
builder.setMessage("message")
builder.setTitle("title")
...
builder.create().show()
以上程式碼,無論構建AlertDialog的流程如何變化,都無需改動程式碼。因為構建過程在builder.create()
方法中,而create()
方法相對於開發者來說是隱藏的,無需關心的。唯一變化的是create()
內部,而這是由Android框架實現的,也就是API釋出方進行維護即可。這大大提高了程式碼的靈活性、可維護性、可擴充套件性。
AlertDialog的核心程式碼如下:
public class AlertDialog extends AppCompatDialog implements DialogInterface {
final AlertController mAlert;
protected AlertDialog(@NonNull Context context) {
this(context, 0);
}
@Override
public void setTitle(CharSequence title) {
super.setTitle(title);
mAlert.setTitle(title);
}
...//省略部分類似setTitle()的程式碼
public static class Builder {
private final AlertController.AlertParams P;
private final int mTheme;
public Builder(@NonNull Context context) {
this(context, resolveDialogTheme(context, 0));
}
public Builder setTitle(@Nullable CharSequence title) {
P.mTitle = title;
return this;
}
...//省略部分類似setTitle()程式碼
public AlertDialog create() {
final AlertDialog dialog = new AlertDialog(P.mContext, mTheme);
P.apply(dialog.mAlert);
dialog.setCancelable(P.mCancelable);
...//省略部分程式碼
return dialog;
}
...//省略部分程式碼
}
}
Builder 是在 AlertDialog 內部實現的靜態類,其主要工作便是通過一系列set方法對 AlertController.AlertParams 物件進行設定,AlertParams類中包含了所有AlertDialog檢視屬性對應的成員變數,比如mTitle、mMessage等等。然後在create()
方法中進行AlertDialog的構建。
Builder模式的實現比較簡單,但是除了“AlertDialog初始化十分複雜,引數繁多”這種應用場景之外,還可以在以下場景中使用Builder模式:
- 構建產品時,不同構建順序會對產品產生不同的效果
- 構建產品時,不同構建元素會對產品產生不同的效果
- 相同方法在以不同執行順序執行時,產生不同結果
總結
Builder模式用於將產品的構建和展示分離。這樣開發者就不必知道產品構建細節,只需對產品的外觀進行設計、配置即可。無需擔心產品構建流程發生變化。其缺點是需要為Builder物件分配記憶體。但這也是大多數設計模式的共同缺點。
版權宣告
本文首發自簡書:搜尋作者 QinGeneral
同步發於CSDN部落格:搜尋作者 迷失
無需授權即可轉載,甚至無需保留以上版權宣告;
轉載時請務必註明作者。