上一篇文章設計模式-單例模式我們介紹了單例模式的幾種用法和優(yōu)缺點梨树,具體的我們需要結合項目中的場景去具體選擇频鉴。這一篇我們來學習Builder模式(有的翻譯為建造者盼产、構建者),builder模式在Android的開發(fā)場景中用的還是挺多的笼吟,比如Android源碼中的AlertDialog、StringBuilder和StringBuffe等等霸旗,三方庫中的GsonBuilder贷帮、EventBus中的builder等等,太常見了诱告,有的人把鏈式調用和builder設計模式搞混撵枢,其實這兩者是完全不同的,Builder設計模式是設計模式的一種精居,鏈式調用是一種函數(shù)調用方式锄禽。
Builder設計模式:
將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創(chuàng)建不同的表示
上面這句話摘自網(wǎng)絡靴姿,說的比較官方沃但,不懂的人還是一頭霧水。沒關系下面我們來舉例說明Builder設計模式是怎么創(chuàng)建出來的佛吓。
咱們還是拿一個經(jīng)典的Person類來講解宵晚,我們定義一個Person類有姓名、年齡维雇、身高淤刃、體重四個基本的屬性:
public class Person {
private String name;
private int age;
private double height;
private double weight;
//為了篇幅省略get、set方法
}
我們可能為了能夠方便的 new 一個對象吱型,定義幾個構造方法:
public Person() {
}
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public Person(String name, int age, double height, double weight) {
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
}
可以看到逸贾,我們定義了幾個構造方法,包括無參津滞、一個參數(shù)铝侵、兩個參數(shù)的等等。
然后我們就可以這樣創(chuàng)建多個Person:
Person p1=new Person();
Person p2=new Person("張三");
Person p3=new Person("李四",18);
Person p4=new Person("王五",21,180);
Person p5=new Person("趙六",17,170,65.4);
但是我們發(fā)現(xiàn)一個問題触徐,參數(shù)一多哟沫,我們根本不清楚參數(shù)代表的具體意義,傳參的時候可能需要點到源碼中查看相關釋義锌介。還有就是當這個類中需要傳入的參數(shù)很多的時候嗜诀,構造方法就會特別多,這樣對我們的開發(fā)和維護是很不利的孔祸,有沒有方法可以解決這個問題呢隆敢?當然,看看我們運用Builder模式是怎么處理這段代碼的:
public class Person {
private String name;
private int age;
private double height;
private double weight;
private Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.height = builder.height;
this.weight = builder.weight;
}
//一大堆get崔慧、set
static class Builder{
private String name;
private int age;
private double height;
private double weight;
public Builder setName(String name){
this.name = name;
return this;
}
public Builder setAge(int age){
this.age = age;
return this;
}
public Builder setHeight(double height){
this.height = height;
return this;
}
public Builder setWeight(double weight){
this.weight = weight;
return this;
}
public Person build(){
return new Person(this);
}
}
}
從上面的代碼我們可以看到:
1.我們創(chuàng)建了一個靜態(tài)的Builder內部類;
2.我們定義了和Person類中一樣的成員變量;
3.Builder中的成員函數(shù)來給這些變量賦值拂蝎,同時返回builder本身;
4.同時提供一個build函數(shù)來創(chuàng)建一個Person對象;
5.在Person對象中存在一個私有的構造函數(shù)來傳入該builder對象依次給Person對象自己的成員變量賦值。
這里有幾點需要說明:
Builder是static修飾的:
靜態(tài)的內部類不持有外部內的引用惶室,如果Builder依賴于外部類温自,那么Builder模式就毫無意義可言玄货;
Person的構造函數(shù)用private修飾:
Person的創(chuàng)建由Builder提供,無需對外暴露悼泌;
關于鏈式調用:
Builder成員函數(shù)返回Builder對象本身松捉,這是為了支持鏈式調用,而鏈式調用是非必需的馆里,使用鏈式調用一般是為了增加易用性和代碼的可讀性隘世。
Builder在Android中的體現(xiàn)
常用的Gson解析創(chuàng)建一個Gson對象斥铺,比如在我的項目中
Gson gson = new GsonBuilder().registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory()).create();
多說一句:這里的NullStringToEmptyAdapterFactory是為了解決服務端返回null,客戶端直接處理導致崩潰的情況
其它的還有StringBuilder浦徊、Okhttp、EventBus悬秉、Glide等等营密,有興趣的話可以去看一看她們的源碼械媒。好了,Builder模式我們講完了评汰,接下來的設計模式系列我將來講講工廠模式纷捞,敬請期待。