1. 程式人生 > >java設計模式-----建造者模式

java設計模式-----建造者模式

建造者模式

  • 定義 : 將一個複雜的物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示.也就是說使用者不需要知道一個複雜的物件時如何建立的.使用者只需要知道使用構造不同物件的方法(Director)就能得到一個完整的複雜物件的例項

  • 建造者模式通常包含的幾個角色

    • Builder :   給出的一個抽象介面,規範產品物件的各個組成部分的建造.這個介面先宣告必須要實現的複雜物件的各個方法.留待他的實現類進行不同的實現.

    • ConcreteBuilder : Builder的實現類,用以構造和裝配該產品的各個部件.定義該產品的表示.

    • Director : 構造的一個使用builder介面的物件,用以建立各個不同表示的例項類.

      • 作用一 : 隔離客戶與物件的生產過程.

      • 作用二 : 負責控制產品物件的生產過程.

    • Product : 被構造的複雜物件.ConcreteBuilder建立該產品的內部表示並定義她的裝配過程.

  • 適用性:

    • 當建立複雜物件的演算法應該獨立於該物件的組成部分以及他們的裝配方式時.

    • 當構造過程必須允許被構造的物件有不同的表示時.

  • 優點 

    • 將複雜物件的建立步驟分解在不同的方法中,使得建立過程更加清晰,能夠幫助我們更加精確的控制複雜物件的產生過程.

    • 產品的建立過程與產品本身分離開來,可以使用相同的建立過程來得到不同的產品.也就說細節依賴抽象.

    • 每一個具體建造者都相互獨立,而與其它的具體建造者無關,因此可以很方便的替換具體建造者或增加新的具體建造者.使用者可以使用不同的具體建造者即可得到不同的產品物件.

  • 缺點 

    • 建造者模式所建立的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不適合使用建造者模式,因此其適用範圍會受到一定的限制.

    • 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化.會導致系統變得很龐大.

建造者模式和抽象工廠模式的區別(貼一個很久在某論壇上看到的挺好解釋)

          在抽象工廠樣式中,每一次工廠物件被呼叫時都會傳回一個完整的產品物件,而使用端有可能會決定把這些產品組裝成一個更大的和複雜的產品,也有可能不會。工廠物件是沒有狀態的,不知道上一次構建的是哪一個產品,也沒有未來的概念,不知道下一次構建的是哪一個產品,更不知道自己構建的產品在更高層的產品結構藍圖中是什麼位置。

        建造類別則不同,建造樣式的重點在導演者角色。導演者物件是有狀態的,它知道整體藍圖,知道上一次、這一次和下一次交給建造者角色去構建的零件是什麼,以便能夠將這些零件組裝成為一個更大規模的產品。它一點一點地建造出一個複雜的產品,而這個產品的組裝程式就發生在導演者角色內部。建造者樣式的使用端拿到的是一個完整的最後產品。

 

     換言之,雖然抽象工廠樣式與建造樣式都是設計樣式,但是抽象工廠樣式處在更加具體的尺度上,而建造樣式則處於更加巨集觀的尺度上。一個系統可以由一個建造樣式和一個抽象工廠樣式組成,使用端通過呼叫這個導演角色,間接地呼叫另一個抽象工廠樣式的工廠角色。工廠樣式傳回不同產品族的零件,而建造者樣式則把它們組裝起來。

 

     比如仍以眾神造人為例,女媧利用建造樣式負責把靈魂、耳目、手臂等組合成一個完整的人,而黃帝、上駢、桑林各自利用工廠樣式創造出靈魂、耳目、臂手等。女媧不必考慮靈魂、耳目、手臂是什麼樣子、怎麼創造出來的,這就成為一個由建造樣式和抽象工廠樣式組合而成的系統。

 

建造者模式例子實現

  • 例子 : 每一個活過75歲的人都一定會有下面的幾個階段:嬰兒, 少年, 青年, 中年, 老年.並且每一個人的各個階段的經歷都會是不一樣的.

程式碼實現

Builder (經歷抽象介面)

package Builder;
 
/**
 * 
 */
public interface LiveBuilder {
  public void buildBaby();
  public void buildChildren();
  public void buildYouth();
  public void buildMidLife();
  public void buildOld();
 
  public PersonLive getPerson();
}

ConcreteBuilder (仲永型天才兒童經歷實現)

package Builder;
 
/**
 * Created by vegetate 
 */
public class GiftedChildrenBuilder implements LiveBuilder {
  private PersonLive personLive;
 
  public GiftedChildrenBuilder(){
    personLive = new PersonLive();
  }
 
  @Override
  public void buildBaby() {
    personLive.setBaby("與眾不同");
  }
 
  @Override
  public void buildChildren() {
    personLive.setChildren("脫穎而出");
  }
 
  @Override
  public void buildYouth() {
    personLive.setYouth("隨父炫耀");
  }
 
  @Override
  public void buildMidLife() {
    personLive.setMidLife("泯然眾人矣");
  }
 
  @Override
  public void buildOld() {
    personLive.setOld("泯然眾人矣");
  }
 
  @Override
  public PersonLive getPerson() {
    return personLive;
  }
}

ConcreteBuilder(姜子牙型老有所成實現)

package Builder;
 
/**
 * 
 */
public class OldSuccessBuilder implements LiveBuilder {
  private PersonLive personLive;
 
  public OldSuccessBuilder(){
    personLive = new PersonLive();
  }
 
  @Override
  public void buildBaby() {
    personLive.setBaby("正常嬰兒");
  }
 
  @Override
  public void buildChildren() {
    personLive.setChildren("學習");
  }
 
  @Override
  public void buildYouth() {
    personLive.setYouth("學習");
  }
 
  @Override
  public void buildMidLife() {
    personLive.setMidLife("學習");
  }
 
  @Override
  public void buildOld() {
    personLive.setOld("老有所成");
  }
 
  @Override
  public PersonLive getPerson() {
    return personLive;
  }
}

Director類

package Builder;
 
/**
 * 
 */
public class LiveDirector {
  public PersonLive generateLive(LiveBuilder liveBuilder){
    liveBuilder.buildBaby();
    liveBuilder.buildChildren();
    liveBuilder.buildYouth();
    liveBuilder.buildMidLife();
    liveBuilder.buildOld();
    return liveBuilder.getPerson();
  }
}

Product(人的經歷類)

package Builder;
 
/**
 * 
 */
public class PersonLive {
  private String baby;
  private String children;
  private String youth;
  private String midLife;
  private String old;
 
  public String getBaby() {
    return baby;
  }
 
  public void setBaby(String baby) {
    this.baby = baby;
  }
 
  public String getChildren() {
    return children;
  }
 
  public void setChildren(String children) {
    this.children = children;
  }
 
  public String getYouth() {
    return youth;
  }
 
  public void setYouth(String youth) {
    this.youth = youth;
  }
 
  public String getMidLife() {
    return midLife;
  }
 
  public void setMidLife(String midLife) {
    this.midLife = midLife;
  }
 
  public String getOld() {
    return old;
  }
 
  public void setOld(String old) {
    this.old = old;
  }
}

測試類

package Builder;
 
/**
 * 
 */
public class BuilderTest {
  public static void main(String[] args) {
    LiveDirector liveDirector = new LiveDirector();
 
    //仲永
    PersonLive zhongyong = liveDirector.generateLive(new GiftedChildrenBuilder());
 
    //姜子牙
    PersonLive jiangziya = liveDirector.generateLive(new OldSuccessBuilder());
  }
 
}