建造者模式(Builder Pattern) ,將一個複雜對象的構建和它的表示分離,使得一樣的建立過程能夠建立不一樣的表示。在Android 中也是很是的常見的,好比:java
/** * 給寶貝撥打電話 * * @param no */ private void CallBaby() { new AlertDialog.Builder(getActivity()) .setTitle(R.string.call_baby) .setMessage(R.string.call_baby_tips) .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { Intent intent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+babyListBean.getFullPhone())); startActivity(intent); } }) .setNegativeButton(R.string.no, null) .show(); }
AlertDialog 的Builder經過setTitle(),setMessage(),setxxButton等方法在create()中構造出一個 AlertDialogInstance對象。而後客戶能夠把把AlertDialogInstance對象show出去。UML 表示以下:web
《Effective Java》P9 第二條:遇到多個構造器參數時候要考慮用構造器(爲了對比又要設計工廠方法)數組
使用Builder模式來替代多參數構造函數是一個比較好的實踐法則。ide
咱們經常會面臨編寫一個這樣的實現類(假設類名叫MemberContact,是關於會員資料的),這個類擁有多個構造函數,函數
MemberContact(String name,String phone);ui
MemberContact(String name, String phone,int age);this
MemberContact(String name, String phone,int age, String address);spa
MemberContact(String name, String phone,int age, String address, int cardID);設計
MemberContact(String name, String phone,int age, String address, int cardID, type ...);代理
這樣一系列的構造函數主要目的就是爲了提供更多的客戶調用選擇,以處理不一樣的構造請求。這種方法很常見,也頗有效力,可是它的缺點也不少。類的做者不得不書寫多種參數組合的構造函數,並且其中還須要設置默認參數值,這是一個須要細心而又枯燥的工做。
其次,這樣的構造函數靈活性也不高,並且在調用時你不得不提供一些沒有意義的參數值,例如,MemberContact("Anylife","10086" ,-1),顯然年齡爲負數沒有意義,可是你又不的不這樣作,得以符合Java的規範。若是這樣的代碼發佈後,後面的維護者就會很頭痛,由於他根本不知道這個-1是什麼含義。對於這樣的狀況,就很是適合使用Builder模式。Builder模式的要點就是經過一個代理來完成對象的構建過程。這個代理職責就是完成構建的各個步驟,同時它也是易擴展的。下面是改寫自Effective Java裏面的一段代碼:
/** * * * @author Anylife.zlb@gmail.com * */ public class MemberContact { private final String name; private final String phone; //一個會員的姓名和電話號碼是必填項目 private final int age; private final int safeID; private final String address; // private final type params... /** * 私有構造方法,在class Builder 中完成Build 後 * return new DoDoContact(Builder instance); * 有點代理的感受哈 * * @param b */ private MemberContact(Builder b) { age = b.age; safeID = b.safeID; name = b.name; address = b.address; phone = b.phone; } // public int getAge() { // return age; // } // // public int getSafeID() { // return safeID; // } // // public String getName() { // return name; // } // // public String getAddress() { // return address; // } public static class Builder { private String name = null; private String phone = null; private int age = 0; private int safeID = 0; private String address = null; public MemberContact build() { // 構建,返回一個新對象 return new MemberContact(this); } public Builder(String name,String phone) { this.name = name;//這兩個是必填的參數 this.phone=phone; } public Builder phone(String val) { phone = val; return this; } public Builder age(int val) { age = val; return this; } public Builder safeID(int val) { safeID = val; return this; } public Builder address(String val) { address = val; return this; } } }
爲所欲爲的調用:
// MemberContact mc1 = new MemberContact.Builder("who").phone(110).address("shenzhen").build();
// MemberContact mc2 = new MemberContact.Builder("anylife").phone(1882656).age(10).address("beijing").build();