Android常見設計模式十:Build模式

對於開發人員來講,設計模式有時候就是一道坎,可是設計模式又很是有用,過了這道坎,它可讓你水平提升一個檔次。而在android開發中,必要的瞭解一些設計模式又是必須的,由於設計模式在Android源碼中,能夠說是無處不在。對於想系統的學習設計模式的同窗,這裏推薦一本書,《大話設計模式》。android


Android經常使用設計模式系列:

面向對象的基礎特徵
面向對象的設計原則
單例模式
模板模式
適配器模式
工廠模式
代理模式
原型模式
策略模式
Build模式
觀察者模式
裝飾者模式
中介模式
門面模式設計模式


Build模式

Build模式是很是常見的設計模式之一,寫個筆記,記錄一下個人學習過程和心得。api

首先了解一些Build模式的定義。網絡

將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示框架

可是看完這個定義,並無什麼卵用,你依然不知道什麼是Builder設計模式。在此我的的態度是學習設計模式這種東西,不要過分在乎其定義,定義每每是比較抽象的,學習它最好的例子就是經過樣例代碼。ide

咱們經過一個例子來引出Builder模式。假設有一個Car類,咱們經過該Car類來構建一大批汽車,這個Car類裏有不少屬性,最多見的好比顏色,價格,品牌,排量等等,而且咱們容許這些值不被設置,也就是容許爲null,該類的定義以下。函數

public class Car  {
    Color color;
    double price;
    String brand;
    String displacement;

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getDisplacement() {
        return displacement;
    }

    public void setDisplacement(String displacement) {
        this.displacement = displacement;
    }
}

而後咱們爲了方即可能會定義一個構造方法。post

public Car(Color color, double price, String brand, String displacement) {
 this.color = color;
 this.price = price;
 this.brand = brand;
 this. displacement = displacement;
}

有時候,只想傳部分參數,你還會定義以下相似的構造方法。學習

public Car(Color color) {
 this.color = color;
}
 public Car(Color color, double price) {
 this.color = color;
 this.price = price;
}
 public Car(Color color, double price, String brand) {
this.color = color;
 this.price = price;
 this.brand = brand;
}

因而你就能夠這樣建立各個須要的對象ui

Person p2=new Person(Color.read);
Person p3=new Person(Color.blue,180000);
Person p4=new Person(Color.green,21180, "小鵬");
Person p5=new Person(Color.white,17170,"法拉利","4.0L");

能夠想象一下這樣建立的壞處,若是四個參都是同一種數據類型,那各個參數究竟是什麼意思,那得考讀性了,。還有一個問題就是當有不少參數時,編寫這個構造數就會顯得異常麻煩,這時候若是換一個角度,試試Builder模式,你會發現代碼的可讀性一會兒就上去了。

咱們給Car增長一個靜態內部類Builder類,並修改Car類的構造函數,代碼以下。

public class Car  {
    Color color;
    double price;
    String brand;
    String displacement;

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getDisplacement() {
        return displacement;
    }

    public void setDisplacement(String displacement) {
        this.displacement = displacement;
    }

    private Car(Builder builder) {
 this.color = builder.color;
 this.price = builder.price;
 this.brand = builder.brand;
 this. displacement = builder.displacement;
    }
    
    
    public static class Builder {

    Color color;
    double price;
    String brand;
    String displacement;
        
        public  Builder color(Color color){
            this.color=color;
            return  this;
        }
        public  Builder price(double price){
            this.price=price;
            return  this;
        }
        public  Builder brand(String brand){
            this.brand=brand;
            return  this;
        }
        public  Builder displacement(String displacement){
            this.displacement=displacement;
            return  this;
        }


        public Car build() {
            return new Car(this);
        }
    }
}

這樣,咱們就不會被Car類構造函數的各個入參搞得稀裏糊塗了。
此外Builder類中的成員函數返回Builder對象自身,讓它支持鏈式調用,使代碼可讀性大大加強。因而咱們就能夠這樣建立Car類。

new Car.Builder().color(Color.BLUE)
                 .price(129800)
                 .pailiang("1.5T")
                 .brand("小鵬")
                 .build();

有沒有以爲建立過程一會兒就變得那麼清晰了。對應的值是什麼屬性一目瞭然,可讀性大大加強。

綜上,咱們總結一下build模式的要點:

1. 定義一個靜態內部類Builder,內部的成員變量和外部類同樣
2. Builder類經過一系列的方法用於成員變量的賦值,並返回當前對象自己(this)
3. Builder類提供一個外部類的建立方法(build、create……),該方法內部調用了外部類的一個私有構造函數,入參就是內部類Builder
4. 外部類提供一個私有構造函數供內部類調用,在該構造函數中完成成員變量的賦值,取值爲Builder對象中對應的成變量的值

模式應用普遍

其實在Android中, Builder模式也是被大量的運用。好比常見的對話框的建立

AlertDialog.Builder builder=new AlertDialog.Builder(this);
AlertDialog dialog=builder.setTitle("標題")
 .setIcon(android.R.drawable.ic_dialog_alert)
 .setView(R.layout.myview)
 .setPositiveButton(R.string.positive, new DialogInterface.OnClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which) {
 }
 })
 .setNegativeButton(R.string.negative, new DialogInterface.OnClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which) {
 }
 })
 .create();
dialog.show();

並且,各個第三方框架也大量的運用了Builder模式
如Gson中的GsonBuilder,代碼太長了,就不貼了,有興趣本身去看源碼,這裏只貼出其Builder的使用方法。

GsonBuilder builder=new GsonBuilder();
Gson gson=builder.setPrettyPrinting()
 .disableHtmlEscaping()
 .generateNonExecutableJson()
 .serializeNulls()
 .create();

再看看著名的網絡請求框架OkHttp

Request.
Builder builder=new Request.Builder();
Request request=builder.addHeader("","")
 .url("")
 .post(body)
 .build();

總結

優勢

Builder模式一般做爲配置類的構建器將配置的構建和表示分離開來,同時也是將配置從目標類中隔離出來,避免做爲過多的setter方法,而且隱藏內部的細節。Builder模式比較常見的實現形式是經過鏈式調用,這樣使得代碼更加簡潔、易懂。

缺點

內部類與外部類相互引用,可能會致使內存消耗比較大,不過鑑於如今的手機內存來說,這點幾乎影響不大。

相關文章
相關標籤/搜索