《JAVA與模式》之建造模式

來源:互聯網
上載者:User

在閻宏博士的《JAVA與模式》一書中開頭是這樣描述建造(Builder)模式的:

  建造模式是對象的建立模式。建造模式可以將一個產品的內部表象(internal representation)與產品的生產過程分割開來,從而可以使一個建造過程產生具有不同的內部表象的產品對象。

產品的內部表象

  一個產品常有不同的組成成分作為產品的零件,這些零件有可能是對象,也有可能不是對象,它們通常又叫做產品的內部表象(internal representation)。不同的產品可以有不同的內部表象,也就是不同的零件。使用建造模式可以使用戶端不需要知道所產生的產品有哪些零件,每個產品的對應零件彼此有何不同,是怎麼建造出來的,以及怎麼組成產品。

對象性質的建造

  有些情況下,一個對象會有一些重要的性質,在它們沒有恰當的值之前,對象不能作為一個完整的產品使用。比如,一個電子郵件有寄件者地址、收件者地址、主題、內容、附錄等部分,而在最起碼的收件者地址得到賦值之前,這個電子郵件不能發送。

  有些情況下,一個對象的一些性質必須按照某個順序賦值才有意義。在某個性質沒有賦值之前,另一個性質則無法賦值。這些情況使得性質本身的建造涉及到複雜的商業邏輯。這時候,此對象相當於一個有待建造的產品,而對象的這些性質相當於產品的零件,建造產品的過程是建造零件的過程。由於建造零件的過程很複雜,因此,這些零件的建造過程往往被“外部化”到另一個稱做建造者的對象裡,建造者對象返還給用戶端的是一個全部零件都建造完畢的產品對象。

  建造模式利用一個導演者對象和具體建造者對象一個個地建造出所有的零件,從而建造出完整的產品對象。建造者模式將產品的結構和產品的零件的建造過程對用戶端隱藏起來,把對建造過程進行指揮的責任和具體建造者零件的責任分割開來,達到責任劃分和封裝的目的。 

建造模式的結構

  

  在這個示意性的系統裡,最終產品Product只有兩個零件,即part1和part2。相應的建造方法也有兩個:buildPart1()和buildPart2()、同時可以看出本模式涉及到四個角色,它們分別是:

  抽象建造者(Builder)角色:給 出一個抽象介面,以規範產品對象的各個組成成分的建造。一般而言,此介面獨立於應用程式的商業邏輯。模式中直接建立產品對象的是具體建造者 (ConcreteBuilder)角色。具體建造者類必須實現這個介面所要求的兩種方法:一種是建造方法(buildPart1和 buildPart2),另一種是返還結構方法(retrieveResult)。一般來說,產品所包含的零件數目與建造方法的數目相符。換言之,有多少 零件,就有多少相應的建造方法。

  具體建造者(ConcreteBuilder)角色:擔任這個角色的是與應用程式緊密相關的一些類,它們在應用程式調用下建立產品的執行個體。這個角色要完成的任務包括:1.實現抽象建造者Builder所聲明的介面,給出一步一步地完成建立產品執行個體的操作。2.在建造過程完成後,提供產品的執行個體。

  導演者(Director)角色:擔任這個角色的類調用具體建造者角色以建立產品對象。應當指出的是,導演者角色並沒有產品類的具體知識,真正擁有產品類的具體知識的是具體建造者角色。

  產品(Product)角色:產品便是建造中的複雜物件。一般來說,一個系統中會有多於一個的產品類,而且這些產品類並不一定有共同的介面,而完全可以是不相關聯的。

  

  導演者角色是與用戶端打交道的角色。導演者將用戶端建立產品的請求劃分為對各個零件的建造請求,再將這些請求委派給具體建造者角色。具體建造者角色是做具體建造工作的,但是卻不為用戶端所知。

  一般來說,每有一個產品類,就有一個相應的具體建造者類。這些產品應當有一樣數目的零件,而每有一個零件就相應地在所有的建造者角色裡有一個建造方法。

原始碼

 產品類Product

public class Product {
/**
* 定義一些關於產品的操作
*/
private String part1;
private String part2;
public String getPart1() {
return part1;
}
public void setPart1(String part1) {
this.part1 = part1;
}
public String getPart2() {
return part2;
}
public void setPart2(String part2) {
this.part2 = part2;
}
}

 抽象建造者類Builder

public interface Builder {
public void buildPart1();
public void buildPart2();
public Product retrieveResult();
}

  具體建造者類ConcreteBuilder

public class ConcreteBuilder implements Builder {

private Product product = new Product();
/**
* 產品零件建造方法1
*/
@Override
public void buildPart1() {
//構建產品的第一個零件
    product.setPart1("編號:9527");
}
/**
* 產品零件建造方法2
*/
@Override
public void buildPart2() {
//構建產品的第二個零件
    product.setPart2("名稱:XXX");
}
/**
* 產品返還方法
*/
@Override
public Product retrieveResult() {
return product;
}

}

   導演者類Director

public class Director {
/**
* 持有當前需要使用的建造器對象
*/
private Builder builder;
/**
* 構造方法,傳入建造器對象
* @param builder 建造器對象
*/
public Director(Builder builder){
this.builder = builder;
}
/**
* 產品構造方法,負責調用各個零件建造方法
*/
public void construct(){
builder.buildPart1();
builder.buildPart2();
}
}

  用戶端類Client

public class Client {
public static void main(String[]args){
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Product product = builder.retrieveResult();
System.out.println(product.getPart1());
System.out.println(product.getPart2());
}
}
時序圖

  用戶端負責建立導演者和具體建造者對象。然後,用戶端把具體建造者對象交給導演者,導演者操作具體建造者,開始建立產品。當產品完成後,建造者把產品返還給用戶端。

  把建立具體建造者對象的任務交給用戶端而不是導演者對象,是為了將導演者對象與具體建造者對象的耦合變成動態,從而使導演者對象可以操縱數個具體建造者對象中的任何一個。

 

使用情境

  假設有一個電子雜誌系統,定期地向使用者的電子郵件信箱發送電子雜誌。使用者可以通過網頁訂閱電子雜誌,也可以通過網頁結束訂閱。當客戶開始訂閱時,系統發送一個電子郵件表示歡迎,當客戶結束訂閱時,系統發送一個電子郵件表示歡送。本例子就是這個系統負責發送“歡迎”和“歡送”郵件的模組。

  在本例中,產品類就是發給某個客戶的“歡迎”和“歡送”郵件,如所示。

  雖然在這個例子裡面各個產品類均有一個共同的介面,但這僅僅是本例子特有的,並不代表建造模式的特點。建造模式可以應用到具有完全不同介面的產品類上。大多數情況下是不知道最終構建出來的產品是什麼樣的,所以在標準的建造模式裡面,一般是不需要對產品定義抽象介面的,因為最終構造的產品千差萬別,給這些產品定義公用介面幾乎是沒有意義的。

  所示就是這個系統的類圖。

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.