Android Builder模式詳解
經典Builder模式
1) 定義:將一個複雜物件的構建與它的表示分離,使得同樣
的構建過程可以建立不同的表示。2) 經典的Builder模式有四個參與者
- Product:被構造的複雜物件
- Builder:抽象介面,用來定義建立Product物件的各個組成部
件的操作。 - ConcreteBuilder:Builder介面的具體實現,可以定義多個,
是實際構建Product物件的類,同時會提供一個返回Product的接
口。 - Director:Builder介面的構造者和使用者。
3) 簡單程式碼形式
public class Product { private
public
public class ConcreteBuilder implements Builder { private Product mProduct; @Override public void buildName() { } @Override public void buildAge() { } @Override public
public class Director { private Builder mBuilder; public Director(Builder builder) { mBuilder = builder; } public void buildProduct() { mBuilder.buildName(); mBuilder.buildAge(); } public Product getProduct() { return mBuilder.getProduct(); } }
4) 經典的Builder模式重點在於抽象出物件建立的步驟,並通過調
用不同的具體實現從而得到不同的、Builder模式的變種(Android Builder模式)
1) 變種的Builder模式的目的在於減少物件建立過程中引用的多
個過載構造方法、可選引數和setters過度使用導致的不必要的復
雜性。下面以一個簡單物件Person物件建立過程為例子說明,它
具有如下所示的屬性,且都是不可變的final的。public class Person{ private final String mName; //必選 private final int mAge; //必選 private final int mGender; //必選 private final String mAddress; //可選 }
由於已經將屬性宣告為final,因此必須在建構函式中對屬性進行
賦值,由於屬性有必選和可選之分,也就是說構造方法需要提供
可以選擇忽略可選引數的方式。兩種方案如下程式碼所示:構造方法初始化
public Person(String name,int age,int gender){ this(name,age,gender,"") } public Person(String name,int age,int gender,String address){ mName = name; mAge = age; mGender = gender; mAddress = address; }
JavaBeans規範(無參構造方法,提供getters和setters方法)
public class Person { private String mName; private int mAge; private int mGender; private String mAddress; public String getmName() { return mName; } public void setmName(String mName) { this.mName = mName; } public int getmAge() { return mAge; } public void setmAge(int mAge) { this.mAge = mAge; } public int getmGender() { return mGender; } public void setmGender(int mGender) { this.mGender = mGender; } public String getmAddress() { return mAddress; } public void setmAddress(String mAddress) { this.mAddress = mAddress; }
JavaBeans方案的好處是易於閱讀和維護,使用Person只需要
建立例項物件,呼叫setters方法設定必要的屬性即可。但這樣
做存在兩個缺點:Person類是可變的;Person類是不連續狀態
的(只有所有的setters方法被呼叫後,才是連續狀態)。
那麼怎樣才可以具有前面方案的優點,又不存在它們的缺點呢
?(變種的Builder模式Android Builder模式)
2) Builder模式的變種(Android Builder模式)
``` public class Person { private final String mName; private final int mAge; private final int mGender; private final String mAddre; private Person(Builder builder) { mName = builder.mName; mAge = builder.mAge; mGender = builder.mGender; mAddre = builder.mAddre; } public int getmAge() { return mAge; } public int getmGender() { return mGender; } public String getmName() { return mName; } public String getmAddre() { return mAddre; } public static final class Builder { private String mName; private int mAge; private int mGender; private String mAddre; public Builder(String name, int age, int gender) { mName = name; mAge = age; mGender = gender; } public Builder mAddre(String val) { mAddre = val; return this; } public Person build() { return new Person(this); } } } ```
Person類的構造方法是私有的,不可以直接通過new來建立例項
Person類是不可變的,對屬性值只提供getter方法
最後,建立一個Person物件``` public Person getPerson() { return new Person.Builder("Wxq", 23, 1) .mAddre("China") .build(); } ```
Android Studio自動生成變種Builder模式
安裝好後重啟Android Studio,只需要把屬性名確定下來,alt鍵+insert鍵,選擇builder按鈕即可(快捷鍵Alt+Shift+B)。
Android中使用Builder模式的例子
1)系統對話的使用Builder模式``` public void showDialog() { AlertDialog alertDialog = new AlertDialog.Builder(this) .setTitle("對話方塊") .setMessage("測試") .setIcon(R.mipmap.ic_launcher) .create(); alertDialog.show(); } ``` 2) ImageLoader使用Builder模式 ``` private void initImageLoader() { ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(getContext()); config.threadPriority(Thread.NORM_PRIORITY - 2); config.denyCacheImageMultipleSizesInMemory(); config.memoryCacheSize(5 * 1024 * 1024);// 5M config.tasksProcessingOrder(QueueProcessingType.LIFO); ImageLoader.getInstance().init(config.build()); } ```