Android Builder設計模式

DIALOG 設計模式 軟件 蘋果公司 天下訪談 2017-03-28

Builder模式是一步一步創建複雜對象的創建型模式。允許用戶在不知道內部構建細節的情況下,可以更精細的控制構造流程。該模式是為了將構建過程和表示分開,使構建過程和部件都可以自由擴展,兩者的耦合度也降到最低。

定義

將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

使用場景

  • 相同的方法,不同的執行順序,產生不同的結果。

  • 多個部件或零件都可以裝配到一個對象中,但產生的運行結果又不相同時。

  • 產品類非常複雜,或者構建部件的順序不同產生了不同的作用。

  • 當初始化一個對象特別複雜時,如參數特別多且很多參數都有默認值的時

    UML類圖

Android Builder設計模式

  • Product 產品的抽象類

  • Builder 抽象的Builder類,規範產品的組建,一般由子類實現具體的構建過程

  • 角色介紹:

  • ConcreteBuilder 具體的Builder類

  • Director 統一組裝類,導演類

    簡單實現

    書中以計算機舉了個例子

  • 先創建計算機的抽象類

    public abstract class Computer { /**
  • 創建計算機的一個實現類 蘋果計算機

    public class Macbook extends Computer {
  • 創建builder的抽象類,規範產品的組建

    public abstract class Builder { public abstract Builder buildBoard(String board); public abstract Builder buildDisplay(String display); public abstract Builder buildOS(); public abstract Computer create();

Android Builder設計模式

  • 創建具體的Builder類,實現蘋果計算機的組裝

    public class MacbookBuilder extends Builder { private Computer mComputer = new Macbook();//這裡的方法返回builder本身,可以鏈式調用

    //調用這個方法生成最終的產品

     @Override
  • 導演類

    public class Director {

    -使用示例

    public class MainM { public static void main(String[] args) {

    -打印結果

    Computer{mBoard='huashuo', mDisplay='sanxing', mOS='macOS'}

    Android源碼中的Builder模式實現

    我們在構建對話框的時候通常都是以下的用法:

    private void showDialog(final Context context) {
  • 可以看出AlertDialog就是通過AlertDialog.Builder來構建的。

AlertDialog源碼:

看著源碼來分析

創建AlertDialog

public class AlertDialog extends Dialog implements DialogInterface { //留意這個變量

在源碼中可以看出,我們通過builder的各種setxxx方法設置一些屬性的時候,builder吧這些設置都存在一個變量P中,這個P在Builder創建時在構造方法中初始化,類型是AlertController.AlertParams,是AlertController的內部類。

然後在Builder的create方法中,new一個新的AlertDialog,並在AlertDialog的構造方法中初始化了AlertDialog的變量mAlert,類型是AlertController。

調用P.apply(mAlert)方法把P中保存的參數傳遞給AlertDialog的變量mAlert。最後返回這個生成的AlertDialog。

看一下這個方法:

package com.android.internal.app;public class AlertController { public static class AlertParams { public void apply(AlertController dialog) {//基本上所有的方法都是把自己的參數設置給傳進來的dialog。

顯示AlertDialog

在上面的使用例子中可以看出,獲取到Dialog後,直接調用alertDialog.show()就能顯示AlertDialog了。

package android.app;public class Dialog implements DialogInterface, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, Window.OnWindowDismissedCallback { public void show() {//如果已經顯示,就直接return

簡單分析一下這個方法的主要流程就是:

(1)先確認AlertDialog的onCreate方法是否執行,如果沒有執行就調用dispatchOnCreate(null)方法來調用AlertDialog的onCreate方法。

(2)調用Dialog的onStart()方法。

(3)將設置好的DecorView添加到WindowManager中。

在AlertDialog的onCreate方法中只有兩行代碼:

@Override

mAlert就是AlertDialog的AlertController類型的變量。

package com.android.internal.app;public class AlertController { public void installContent() {//獲取相應的對話框內容的佈局

分析LayoutInflater時就知道,Activity的setContentView最後也是調用了Window.setContentView這個方法。所以這個方法裡主要就是給對話框設置佈局。

private int selectContentView() { if (mButtonPanelSideLayout == 0) { return mAlertDialogLayout;

看到通過selectContentView()獲得的佈局是mAlertDialogLayout,那麼這個佈局是什麼時候初始化的呢?

在AlertController的構造方法中可以看見:

 protected AlertController(Context context, DialogInterface di, Window window) { mContext = context; mDialogInterface = di; mWindow = window; mHandler = new ButtonHandler(di);

好,來看一下佈局文件,也就是alert_dialog.xml

默認的佈局是這樣的,本來文件中是空白的,為了能看出來,我給佈局設置了一些值和背景色:

Android Builder設計模式

系統默認的dialog佈局

源代碼貼出來,可以自己試試:

alert_dialog.xml<LinearLayout

回到AlertController的installContent()方法中,看下一行代碼setupView();

private void setupView() {//獲取alert_dialog.xml中的佈局

所以setupView的流程就是:

(1)初始化AlertDialog佈局中的各個部分

(2)佈局全部設置完畢後,又通過Window對象關聯到DecorView。並將DecorView添加到用戶窗口上顯示出來。

總結

優點

  • 良好的封裝性,使用Builder模式可以使客戶端不必知道產品的內部組成的細節

  • builder獨立,容易擴展

    缺點

  • 會產生多餘的Builder對象以及Director對象(用的不多),消耗內存

相關推薦

推薦中...