設(shè)計模式 - 建造者模式 Builder

1.介紹

允許用戶在不知道內(nèi)部構(gòu)建細(xì)節(jié)的情況下,可以更精細(xì)地控制對象的構(gòu)造流程。為了將構(gòu)建復(fù)雜對象的過程和它的部件解耦,使得構(gòu)建過程和部件的表示隔離。

1.這個對象由多個小部分組成
2.可以配置該對象由其中哪幾個分類組成
3.不同的組成,可以得到不同的結(jié)果。(雖然都是同一類對象,但細(xì)節(jié)上不一樣)

2.定義

建造者模式(Builder),見一個復(fù)雜對象的構(gòu)建與它的標(biāo)識分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。

3.使用場景

    1. 相同的方法,不同的執(zhí)行循序,產(chǎn)生不同的時間結(jié)果時。
    1. 多個部件或零件,都可以裝配到一個對象中,但是產(chǎn)生的運行結(jié)果又不相同。
    1. 產(chǎn)品類非常復(fù)雜,或者產(chǎn)品類中的調(diào)用循序不同產(chǎn)生了不同的作用,這個時候使用建造者模式非常適合。
    1. 當(dāng)初始化一個對象非常復(fù)雜,如參數(shù)多且很多參數(shù)都有默認(rèn)值時。

簡單理解就是:當(dāng)創(chuàng)建對象時參數(shù)過多、創(chuàng)建過程復(fù)雜、得到的結(jié)果多變時可以考慮使用 Builder 模式。

舉個例子

一個游戲扮演游戲,如王者農(nóng)藥。我們在操作時可以選擇不同的人物角色,他們有之間的劃分:

    1. 人物名稱:李元芳(輸出爆炸)、呂布(團(tuán)戰(zhàn)跳大收割)、程咬金(瘋狂補血)、安其拉(大頭發(fā))...我基本上玩這幾個吧
    1. 人物類型有:戰(zhàn)士、坦克、刺客、法師、射手。
    1. 武器:激光射線、雙斧、斬刀、飛刀...
    1. 發(fā)型:超長頭發(fā)、短發(fā)、禿頭、配大耳朵的頭發(fā)
    1. 戰(zhàn)斗類型:持續(xù)輸出、收割、遠(yuǎn)程攻擊、生存等

如果使用普通的方式構(gòu)建對象可能會是這樣的:

public Hero(String name,Profession profession, Weapon weapon ,HairType hairType, Armor armor) {
}

可以看出這樣做的缺點:

  • 1、參數(shù)超多,容易誤導(dǎo)或傳錯或位子放錯。
  • 2、當(dāng)有新的類型添加時,之前創(chuàng)建的角色都要修改。

那么怎么辦呢? 很容易想到:構(gòu)造函數(shù)中直接傳遞個 POJO 不就行了?! 確實是這樣的,但是我們還可以做些改變,使得這個 POJO 更方便使用:

  • 1、這個 POJO 基本上只屬于這個類使用,所以我們一般都定義在該類中。
  • 2、這個 POJO 的構(gòu)造函數(shù)不能是多個參數(shù)了,它的出現(xiàn)就是為了解決參數(shù)過多的問題,當(dāng)然就不能有多參數(shù)的構(gòu)造(可以有一兩個參數(shù)的構(gòu)造)。
  • 3、這個 POJO 在配置的時候,希望是鏈?zhǔn)降?,這樣更方便了是吧,直接點點點點... 的就可以創(chuàng)建了。
  • 4、既然有了這個 POJO 就不能讓原來對象被外部創(chuàng)建了是吧,那么外部的對象類的構(gòu)造函數(shù)就應(yīng)該設(shè)置為 private 防止外部創(chuàng)建。
  • 5、直接叫 POJO 不太好聽吧,那么重新定義個名字唄,(⊙v⊙)嗯,它是用來創(chuàng)建復(fù)雜對象的,那就叫 Builder 吧。

Talk is cheap,show me the code

我們先來看下 Builder 類吧:

  public static class Builder {
    private final String name;  // 名稱
    private final Profession profession; // 類型
    private HairType hairType; // 發(fā)型
    private Armor armor; // 戰(zhàn)斗類型
    private Weapon weapon; // 武器

    public Builder(Profession profession, String name) {
      if (profession == null || name == null) {
        throw new IllegalArgumentException("profession and name can not be null");
      }
      this.profession = profession;
      this.name = name;
    }

    public Builder withHairType(HairType hairType) {
      this.hairType = hairType;
      return this;
    }

    public Builder withArmor(Armor armor) {
      this.armor = armor;
      return this;
    }

    public Builder withWeapon(Weapon weapon) {
      this.weapon = weapon;
      return this;
    }

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

那么我們回頭看下 Hero 類發(fā)生了什么變化吧:

public final class Hero {
  private final Profession profession;
  private final String name;
  private final HairType hairType;
  private final Armor armor;
  private final Weapon weapon;

  private Hero(Builder builder) {
    this.profession = builder.profession;
    this.name = builder.name;
    this.hairColor = builder.hairColor;
    this.weapon = builder.weapon;
    this.armor = builder.armor;
  }
}

不得不承認(rèn),代碼是多了不少,但是為了以后應(yīng)對更好理解、需求變化,還是認(rèn)了吧。程序里面唯一不變的就是變化

我們再看下爽點的地方,對象的創(chuàng)建過程:

Hero mage = new Hero.Builder(Profession.MAGE, "安其拉")
  .withHairColor(HairColor.RED)
  .withWeapon(Weapon.LASER)
  .build();

參考:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 定義 建造模式是對象的創(chuàng)建模式。建造模式可以將一個產(chǎn)品的內(nèi)部表象(internal representation)...
    步積閱讀 7,202評論 1 7
  • 總體說來,建造者模式適合于一個具有較多的零件(屬性)的產(chǎn)品(對象)的創(chuàng)建過程。根據(jù)產(chǎn)品創(chuàng)建過程中零件的構(gòu)造是否具有...
    一凡和梓墨閱讀 208評論 0 0
  • 工廠類模式提供的是創(chuàng)建單個類的模式,而建造者模式則是將各種產(chǎn)品集中起來進(jìn)行管理,用來創(chuàng)建復(fù)合對象,所謂復(fù)合對象就是...
    曉瘋閱讀 290評論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,697評論 19 139
  • 沒有人買車會只買一個輪胎或者方向盤,大家買的都是一輛包含輪胎、方向盤和發(fā)動機等多個部件的完整汽車。如何將這些部件組...
    justCode_閱讀 2,009評論 1 6

友情鏈接更多精彩內(nèi)容