1. 程式人生 > >Android設計模式(一)—— 建造者模式

Android設計模式(一)—— 建造者模式

    其實設計模式,只是一種定式,適用於不同的語音,今天,雖然加上了Andorid的字首,只是因為舉例僅是android程式碼,所以學好內在,則舉例僅是舉例,內涵才是到處通用的。

建造者模式解釋:

建造者模式(Builder Pattern)又叫生成器模式,是GoF提出的23種設計模式中的一種。

    建造者模式是一種物件建立型模式之一,用來隱藏複合物件的建立過程,它把複合物件的建立過程加以抽象,通過子類繼承和過載的方式,動態地建立具有複合屬性的物件。

英文定義為:Separate the construction of a complex object from its representation so that the same construction process can create different representations.

建造者模式涉及以下的角色:

抽象建造者(Builder)角色:給出一個抽象介面,以規範產品物件的各個組成成分的建造。此介面中一般至少規定兩個方法,一個是建立部分的方法,例如BuilderPart,另一個是返回結果的方法,例如GetProduct,以約束具體建造者實現。
具體建造者(ConcreteBuilder)角色:擔任這個角色的是與應用程式緊密相關的一些類,它們在應用程式的呼叫下建立產品的例項。這個角色產品實現了抽象建造者介面,主要完成分步建立產品並提供產品物件的例項。
導演者(Director)角色:顧名思義,就是具體指揮使用哪個具體創造者來完成產品的建立,是建立工作的呼叫者。但是,導演者角色並沒有產品類的具體知識,真正擁有產品類的具體知識的是具體建造者角色。
產品(Product)角色

:產品角色就是建造中的複雜物件。一般只有對於複雜物件的建立才使用建造者模式,一個系統中會出現多於一個的產品類,而這些產品類並不一定有共同的介面,可能完全不關聯,這時就需要提供多套抽象和具體的建造者來完成不一致的產品的建立或者是採用一個統一介面來標識產品。

建造者模式的UML圖如下所示:


建造者模式深入分析:

     在軟體系統中,有時候面臨著“一個複雜物件”的建立工作,其通常由各個部分的子物件用一定的演算法構成;由於需求的變化,這個複雜物件的各個部分經常面臨著劇烈的變化,但是將它們組合在一起的演算法確相對穩定。如何應對這種變化?如何提供一種“封裝機制”來隔離出“複雜物件的各個部分”的變化,從而保持系統中的“穩定構建演算法”不隨著需求改變而改變?這就是要說的建造者模式。

      建造者模式將複雜物件的構建與物件的表現分離開來,這樣使得同樣的構建過程可以創建出不同的表現。 


建造者模式使用場景分析及程式碼實現:

一個人有姓名、性別、年齡、身高,體重這五個屬性組成,當我們建立一個人這個物件的時候,我們可能有下面這些情況:

1、只希望指定姓名 
2、只希望指定性別 
3、只希望指定年齡 
4、只希望指定身高 
5、只希望指定體重 
6、只希望指定姓名和性別 
7、只希望指定姓名和年齡 
8、只希望指定姓名和身高 
9、只希望指定姓名和體重 
10、只希望指定性別和年齡 
11、只希望指定性別和身高 
12、……

上面就不一樣列舉了,就是一個排列組合問題,是不是有些凌亂了,如果一個物件的屬性更多,那情況就更多了,顯然把所以執行情況的建構函式都寫出來不是一個明智的選擇,因為想想你要寫多少個建構函式,好恐怖,不敢想象。

那我們有沒有一種方法來解決這個問題呢?這裡我們就要使用建造者模式,它就是單獨的來對一個物件進行構造,將一個複雜的構建與其表示相分離,使得同樣的構建過程可以建立不同的表示。也就是說它來完成物件的構造過程,並且這個過程可以構造出上面我們所說的所有我們希望得到的物件。

建造模式是將複雜的內部建立封裝在內部,對於外部呼叫的人來說,只需要傳入建造者和建造工具,對於內部是如何建造成成品的,呼叫者無需關心。

針對上面所說的那個包含了5個屬性的物件,我們使用構建者模式如何完成,下面我們來看看。

1、定義一個Person類,他包含了所有屬性的get,set方法。

public class Person {
    private String name;
    private boolean sex;
    private int age;
    private float height;
    private float weight;


    public Person(String name, boolean sex, int age, float height, float weight) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.height = height;
        this.weight = weight;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2、建立一個Builder類

public class Builder {
    private String name;
    private boolean sex;
    private int age;
    private float height;
    private float weight;

    public Builder setName(String name) {
        this.name = name;
        return this;
    }

    public Builder setSex(boolean sex) {
        this.sex = sex;
        return this;
    }

    public Builder setAge(int age) {
        this.age = age;
        return this;
    }

    public Builder setHeight(float height) {
        this.height = height;
        return this;
    }

    public Builder setWeight(float weight) {
        this.weight = weight;
        return this;
    }

    public Person create() {
        return new Person(name, sex, age, height, weight);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

上面我們就寫好了這個構造過程了。現在就可以根據我們的需要來得到任何我們想要的物件。

Builder builder = new Builder();
builder.setName("Mirhunana");
builder.setAge(23);
Perons person = builder.create();
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

上面我們就得到了一個我們想要的物件,很方便,很簡單。

下面為了說明這個完整的過程,我們對上面我們寫的那個構建者模式進行改進。

1、產品類Product 
就是上面的Person

2、抽象建造者類Builder,就是上面的Builder的介面,目的就是為了為構造者提供統一的介面

public interface Builder {

    public Builder setName(String name);

    public Builder setSex(boolean sex);

    public Builder setAge(int age);

    public Builder setHeight(float height);

    public Builder setWeight(float weight);

    public Person create();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

3、 具體建造者類ConcreteBuilder,就是前面的Builder,只是它實現了一個共同的Builder介面

public class ConcreteBuilder implements Builder {
    private String name;
    private boolean sex;
    private int age;
    private float height;
    private float weight;

    public Builder setName(String name) {
        this.name = name;
        return this;
    }

    public Builder setSex(boolean sex) {
        this.sex = sex;
        return this;
    }

    public Builder setAge(int age) {
        this.age = age;
        return this;
    }

    public Builder setHeight(float height) {
        this.height = height;
        return this;
    }

    public Builder setWeight(float weight) {
        this.weight = weight;
        return this;
    }

    public Person create() {
        return new Person(name, sex, age, height, weight);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

4、導演者類Director,它就是操作builder物件的

public class Director {
    private Builder builder;

    public Director(Builder builder){
        this.builder = builder;
    }

    public void construct(String name, boolean sex, int age, float height, float weight) {
        builder.setName(name);
        builder.setSex(sex);
        builder.setAge(age);
        builder.setHeight(height);
        builder.setWeight(weight);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

5、客戶端程式碼

public class Test {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director pcDirector = new Director(builder);
        pcDirector.construct("Mirhunana", true, 23, 180, 100);
        Person person = builder.create();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

建造者模式的優缺點分析:

優點:

在建造者模式中,客戶端不用在直接負責物件的建立,而是把這任務交給了具體的建立者類,把具體的如何組裝的責任交給了Director類,客戶端之負責物件的呼叫即可,符合單一職責原則。而且由於可以選擇不同的具體的建立者,所以可以有不同的形式展現物件。     

缺點:

建立者模式比較符合產品差別不大的物件的建立,如果差別很大,就會導致非常多的具體的建立者,這時候最好結合工廠方法模式。

建造者模式的實際應用簡介:

物件的建立:Builder模式是為物件的建立而設計的模式

建立的是一個複合物件:被建立的物件為一個具有複合屬性的符合物件

關注物件建立各部分的建立過程,不同的工廠對產品的屬性有不同的建立的方法。

溫馨提示:

    建造者模式是為了解決複合物件的建立而生的,建造者模式將複雜物件的構建與物件的表現分離開來,這樣使得同樣的構建過程可以創建出不同的表現。有利明確各部分的職責目標,有利於軟體結構的優化。


---------------------------------------------------------------------------------------------------------------------------

Android中的構建者模式,最經典的就是AlertDialog了。