成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

從ES6重新認識JavaScript設(shè)計模式(三): 建造者模式

yuanxin / 1589人閱讀

摘要:書籍建造者類調(diào)用建造者高效能人士的七個習(xí)慣史蒂芬柯維勵志上面的這個類和第一個例子的效果一樣,但是長度確減少不少,在有更多屬性的時候,減少的代碼量會更為明顯。參考內(nèi)容設(shè)計模式張容銘

1 什么是建造者模式?

建造者模式(Builder)是將一個復(fù)雜對象的構(gòu)建層與其表示層相互分離,同樣的構(gòu)建過程可采用不同的表示。

建造者模式的特點是分步構(gòu)建一個復(fù)雜的對象,可以用不同組合或順序建造出不同意義的對象,通常使用者并不需要知道建造的細節(jié),通常使用鏈式調(diào)用來進行建造過程,最后調(diào)用build方法來生成最終對象。

同樣作為創(chuàng)建型的設(shè)計模式,需要注意和工廠模式的區(qū)別,工廠雖然也是創(chuàng)建對象,但怎樣創(chuàng)建無所謂,工廠模式關(guān)注的是創(chuàng)建的結(jié)果;而建造者模式不僅得到了結(jié)果,同時也參與了創(chuàng)建的具體過程,適合用來創(chuàng)建一個復(fù)雜的復(fù)合對象。

2 ES6中的建造者模式

下面我們來假設(shè)一個出版社的書籍后臺錄入系統(tǒng)的業(yè)務(wù)場景,書籍有四個必填信息,分別是:書名,作者,價格,分類;我們希望創(chuàng)建一個書籍對象返回給后端。下面我們來一步一步深入使用ES6的語法結(jié)合建造者模式創(chuàng)建對象。

//書籍建造者類
class BookBuilder {
  constructor() {
    this.name = "";
    this.author = "";
    this.price = 0;
    this.category = "";
  }
  
  withName(name) {
    this.name = name;
    return this;
  }

  withAuthor(author) {
    this.author = author;
    return this;
  }

  withPrice(price) {
    this.price = price;
    return this;
  }

  withCategory(category) {
    this.category = category;
    return  this;
  }

  build() {
    return {
      name: this.name,
      author: this.author,
      prices: this.price,
      category: this.category
    }
  }
}

//調(diào)用建造者類
const book = new BookBuilder()
  .withName("高效能人士的七個習(xí)慣")
  .withAuthor("史蒂芬·柯維")
  .withPrice(51)
  .withCategory("勵志")
  .build();

上面就通過我BookBuilder這個創(chuàng)建者類的寫法和調(diào)用方法,但是僅僅是一個4個屬性的對象,我們使用了如此多的代碼去創(chuàng)建,這遠比直接在constructor傳遞參數(shù)創(chuàng)建對象要復(fù)雜得多。這是由于在創(chuàng)建的過程中,我們有太多的withxxxx方法。我們其實可以自動創(chuàng)建這類withxxxx方法以簡化代碼。

//書籍建造者類
class BookBuilder {
  constructor() {
    this.name = "";
    this.author = "";
    this.price = 0;
    this.category = "";
  
    Object.keys(this).forEach(key => {
      const withName = `with${key.substring(0, 1).toUpperCase()}${key.substring(1)}`;
      this[withName] = value => {
        this[key] = value;
        return this;
      }
    })
  }
  
  //調(diào)用建造者
  build() {
    const keysNoWithers = Object.keys(this).filter(key => typeof this[key] !== "function");

    return keysNoWithers.reduce((returnValue, key) => {
      return {
        ...returnValue,
        [key]: this[key]
      }
    }, {})
  }
}

const book = new BookBuilder()
  .withName("高效能人士的七個習(xí)慣")
  .withAuthor("史蒂芬·柯維")
  .withPrice(51)
  .withCategory("勵志")
  .build();

上面的BookBuilder這個類和第一個例子的效果一樣,但是長度確減少不少,在有更多屬性的時候,減少的代碼量會更為明顯。我們將所有的建造方法withxxxxconstructor調(diào)用時自動被創(chuàng)建,這里我們使用了一些ES6的新語法:Object.keys獲取對象屬性數(shù)組,...的合并對象的語法。

雖然該寫法在閱讀起來會比第一個方法難以理解,但是這樣寫法的真正作用在于,當我們需要許多的建造者類時,我們可以將上面自動創(chuàng)建withxxxbuild的代碼提取為一個父類。在創(chuàng)建其他建造者類時繼承該父類,這使得在創(chuàng)建多個建造者類時變得十分容易。

//父類
class BaseBuilder {
  init() {
    Object.keys(this).forEach(key => {
      const withName = `with${key.substring(0, 1).toUpperCase()}${key.substring(1)}`;
      this[withName] = value => {
        this[key] = value;
        return this;
      }
    })
  }

  build() {
    const keysNoWithers = Object.keys(this).filter(key => typeof this[key] !== "function");

    return keysNoWithers.reduce((returnValue, key) => {
      return {
        ...returnValue,
        [key]: this[key]
      }
    }, {})
  }
}

//子類1: 書籍建造者類
class BookBuilder extends BaseBuilder {
  constructor() {
    super();

    this.name = "";
    this.author = "";
    this.price = 0;
    this.category = "";
    
    super.init();
  }
}

//子類2: 印刷廠建造者類
class printHouseBuilder extends BaseBuilder {
  constructor() {
    super();

    this.name = "";
    this.location = "";
    this.quality = "";

    super.init();
  }
}

//調(diào)用書籍建造者類
const book = new BookBuilder()
  .withName("高效能人士的七個習(xí)慣")
  .withAuthor("史蒂芬·柯維")
  .withPrice(51)
  .withCategory("勵志")
  .build();


//調(diào)用印刷廠建造類
const printHouse = new printHouseBuilder()
  .withName("新華印刷廠")
  .withLocation("北京海淀區(qū)")
  .withQuality("A")
  .build();
總結(jié)

在之前提到的幾種工廠模式中,他們都有一個共同特點,就是對象的創(chuàng)建過程不得而知,我們在調(diào)用一個函數(shù)后返回了最終的結(jié)果對象。但是在創(chuàng)建者模式中我們關(guān)心的是對象的創(chuàng)建過程,我們通常將創(chuàng)建復(fù)雜對象的各個類模塊化,在ES6中,我們采用importexport的語法可以很靈活的引用和導(dǎo)出這些模塊進行我們的建造模式最終生成一個結(jié)果對象。

可以看出,建造者模式的使用有且只適合創(chuàng)建極為復(fù)雜的對象。在前端的實際業(yè)務(wù)中,在沒有這類極為復(fù)雜的對象的創(chuàng)建時,還是應(yīng)該直接使用對象字面或工廠模式等方式創(chuàng)建對象。

參考內(nèi)容: 
[1] An Exploration of JavaScript Builders —— Ryan Oglesby
[2] 《 JavaScript設(shè)計模式 》—— 張容銘

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/107896.html

相關(guān)文章

  • ES6重新認識JavaScript設(shè)計模式(): 建造模式

    摘要:書籍建造者類調(diào)用建造者高效能人士的七個習(xí)慣史蒂芬柯維勵志上面的這個類和第一個例子的效果一樣,但是長度確減少不少,在有更多屬性的時候,減少的代碼量會更為明顯。參考內(nèi)容設(shè)計模式張容銘 showImg(https://segmentfault.com/img/remote/1460000015147692); 1 什么是建造者模式? 建造者模式(Builder)是將一個復(fù)雜對象的構(gòu)建層與其表...

    hatlonely 評論0 收藏0
  • JavaScript設(shè)計模式系列建造模式

    摘要:優(yōu)點建造者模式的封裝性很好,對象本身與構(gòu)建過程解耦。建造者模式很容易進行擴展。適用場景需要生成的對象具有復(fù)雜得內(nèi)部結(jié)構(gòu)且內(nèi)部屬性本身相互依賴建造者模式的代碼實現(xiàn)建造者模式主要有個部分產(chǎn)品類建造者類指揮者類客戶。建造者完成相應(yīng)的部分。 建造者模式 建造者模式(builder pattern)比較簡單,它屬于創(chuàng)建型模式的一種,將一個復(fù)雜的對象分解成多個簡單的對象來進行構(gòu)建,將復(fù)雜的構(gòu)建層與...

    CloudDeveloper 評論0 收藏0
  • 細談JavaScript中的一些設(shè)計模式

    摘要:注意事項聲明函數(shù)時候處理業(yè)務(wù)邏輯區(qū)分和單例的區(qū)別,配合單例實現(xiàn)初始化構(gòu)造函數(shù)大寫字母開頭推薦注意的成本。簡單工廠模式使用一個類通常為單體來生成實例。 @(書籍閱讀)[JavaScript, 設(shè)計模式] 常見設(shè)計模式 一直對設(shè)計模式不太懂,花了一下午加一晚上的時間,好好的看了看各種設(shè)計模式,并總結(jié)了一下。 設(shè)計模式簡介 設(shè)計模式概念解讀 設(shè)計模式的發(fā)展與在JavaScript中的應(yīng)用 ...

    30e8336b8229 評論0 收藏0
  • ES6重新認識JavaScript設(shè)計模式: 裝飾器模式

    摘要:什么是裝飾器模式向一個現(xiàn)有的對象添加新的功能,同時又不改變其結(jié)構(gòu)的設(shè)計模式被稱為裝飾器模式,它是作為現(xiàn)有的類的一個包裝。中的裝飾器模式中有一個的提案,使用一個以開頭的函數(shù)對中的及其屬性方法進行修飾。 1 什么是裝飾器模式 showImg(https://segmentfault.com/img/remote/1460000015970102?w=1127&h=563); 向一個現(xiàn)有的對...

    wendux 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<