1. 設計模式之工廠模式

1、介紹javascript

每當我聽到有人討論設計模式時,我聽到最多的概念好像就是「工廠模式」,他就像是背單詞時候的「abandon」,它易於理解且常常用到,因此我也將它做爲學習「設計模式」的第一步。前端

咱們都知道,工廠模式是爲了建立對象而存在的(主要是聽到的太多了~)。對象是一個系統的基石,咱們編寫的功能均可以抽象成由一個個對象組合而成,請求是由一個個XmlHttpRequest對象執行的、頁面由一個個DOM節點對象堆砌而成等等。咱們在前端框架之中每每會對請求做一層層的封裝(好比咱們會在JQuery.ajax、axios之上再封裝一層),那咱們在生成這些對象的時候,會發現他們都有着類似之處,就像是由工廠生產出來的一個個產品,那咱們封裝的過程其實就和「工廠模式」很相近了。java

工廠模式屬於「建立型模式」的一種,與之相關的有:簡單工廠模式工廠模式抽象工廠模式ios

2、簡單工廠模式

簡單工廠模式能夠理解爲「一家工廠根據不一樣的模具來生產產品」的模式,以下舉例:git

// 工廠
class SimpleRequestFactory {
    constructor() {}

    createRequest(type) {
        let req = null;
        switch (type) {
            case 'get':
                req = new GetRequest(); // GetRequest爲get請求的模具
                break;
            case 'post':
                req = new PostRequest(); // PostRequest爲post請求的模具
                break;
        }

        return req;
    }
}

// 工廠生產處get請求的產品
const getRequestInstance = SimpleRequestFactory.createRequest('get');
getRequestInstance.setUrl('https://xxx'); // 設置get請求的url
getRequestInstance.setParams({id: 'xxx'}); // 設置get請求的參數
getRequestInstance.request();

// 工廠生產處post請求的產品
const postRequestInstance = SimpleRequestFactory.createRequest('post');
postRequestInstance.setUrl('https://xxx'); // 設置post請求的url
postRequestInstance.setParams({id: 'xxx'}); // 設置post請求的參數
getRequestInstance.request();

以上就是簡單工廠模式運行模式,利用這種方式,咱們就能夠根據不一樣請求的須要,來不斷生產request請求對象,咱們並不須要關心request的實例對象是怎麼生成的,咱們只須要獲得它、使用它便可。github

因此「簡單工廠模式」的特色就是:ajax

  • 咱們只須要知道咱們要生產的產品的名稱便可
  • 咱們不須要知道產品怎麼來的,咱們只須要知道產品怎麼用

由上面的代碼咱們也能看出,簡單工廠模式是具備三大要素的:axios

  • 工廠類:由它根據模具來生產產品
  • 模具類(抽象類產品):它是全部產品的基石,咱們根據它們來獲得用戶使用的產品
  • 產品對象:簡單工廠模式的建立目標,用戶最終使用的就是具體的產品對象

3、工廠模式

工廠模式是在簡單工廠模式之上作了優化處理以後造成一種模式,咱們先看有關於工廠模式的代碼設計模式

class RequestFactory {
    constructor() {}

    createRequest() {
        // 我只表明每種RequestFactory都要實現createRequest方法
        // 而我不生產任何產品
    }
}

// get請求的工廠
class GetRequestFactory extends RequestFactory {
    constructor() {}

    createRequest() {
        return new GetRequest();
    }
}

// post請求的工廠
class PostRequestFactory extends RequestFactory {
    constructor() {}

    createRequest() {
        return new PostRequest();
    }
}

// put請求的工廠
class PutRequestFactory extends RequestFactory {
    constructor() {}

    createRequest() {
        return new PutRequest();
    }
}

// 生產get請求的產品
const getRequestIns = GetRequestFactory.createRequest();
getRequestIns.setUrl('https://xxx'); // 設置get請求的url
getRequestIns.setParams({id: 'xxx'}); // 設置get請求的參數
getRequestIns.request();

// 生產post請求的產品
const postRequestIns = PostRequestFactory.createRequest();
postRequestIns.setUrl('https://xxx'); // 設置get請求的url
postRequestIns.setParams({id: 'xxx'}); // 設置get請求的參數
postRequestIns.request();

// 生產put請求的產品
const putRequestIns = PutRequestFactory.createRequest();
putRequestIns.setUrl('https://xxx'); // 設置get請求的url
putRequestIns.setParams({id: 'xxx'}); // 設置get請求的參數
putRequestIns.request();

由上面的代碼能夠看出,咱們把每一種請求的生產工廠都獨立出來了,看似沒有簡單工廠模式方便,可是咱們能夠在生活之中找到例子輔助理解。前端框架

好比咱們A公司是一家生產飲品的公司,咱們最開始有一條生產線專門生產礦泉水,咱們叫「XX山泉」,後來咱們發現礦泉水作的不錯,咱們想多作一些產品,如「XX AD鈣奶」和「XX 純牛奶」,那咱們應該怎麼作呢?這時咱們可能根據生活中看到的例子,能夠想到,咱們只要照搬A公司的基礎部門(如行政),再成立幾家公司,分別生產「XX AD鈣奶」和「XX 純牛奶」便可。那咱們爲何不在A公司的基礎上不斷擴充生產線呢?由於一旦生產線愈來愈多,管理就愈來愈複雜,咱們須要不斷地折騰A公司,還不如複製一個抽象公司,而後專事專作。

上面的例子就是爲了幫助咱們理解「簡單工廠模式」和「工廠模式」的區別的,那咱們何時用哪一種模式呢?個人理解就是:

  • 若是系統簡單,須要生成的對象類型可數,就用「簡單工廠模式」
  • 若是系統存在擴展的可能性,且咱們沒法預計將來擴展的規模,就用「工廠模式」

其實上面說的也關乎到設計模式中的一個原則——「開閉原則」

再回到「工廠模式」之上,咱們能夠看到工廠模式的特色就是:

  • 符合「開閉原則」,易於擴展
  • 會增長系統的複雜度

「工廠模式」包含四大要素:

  • 抽象工廠:抽象工廠不是一家實際的公司,可是他擁有全部公司共同點
  • 實體工廠:實體工廠負責生產具體的產品
  • 模具(抽象產品):咱們根據模具來生產產品
  • 實體產品:用戶最終獲得並使用實體產品

3、抽象工廠模式

此時確定有朋友想到了一個問題:「現實中咱們也並非全部的工廠都只生產一類產品,牛奶工廠能夠生產純牛奶、酸奶等等」,這就是咱們提到的抽象工廠模式了。示例代碼以下

// 抽象工廠
class RequestFactory {
    constructor() {}

    createRequest() {
        // 我只表明每種RequestFactory都要實現createRequest方法
        // 而我不生產任何產品
    }
}

/** 看這 start **/
// 抽象的get請求
class GetRequest{
    constructor() {}

    request() {}
}

// 簡單的get請求(不須要帶參數的get請求)
class SimpleGetRequest extends GetRequest{
    constructor() {}

    request() {}
}

// 普通的get請求
class NormalGetRequest extends GetRequest{
    constructor() {}

    request() {}
}

// 抽象的post請求
class PostRequest{
    constructor() {}

    request() {}
}

// 簡單的post請求(不須要帶參數的post請求)
class SimplePostRequest{
    constructor() {}

    request() {}
}

// 普通的post請求
class NormalPostRequest extends PostRequest{
    constructor() {}

    request() {}
}
/** 看這 end **/

// get請求的工廠
class GetRequestFactory extends RequestFactory {
    constructor() {}

    createSimpleRequest() {
        return new SimpleGetRequest();
    }

    createNormalRequest() {
        return new NormalGetRequest();
    }
}

// post請求的工廠
class PostRequestFactory extends RequestFactory {
    constructor() {}

    createSimpleRequest() {
        return new SimplePostRequest();
    }

    createNormalRequest() {
        return new NormalPostRequest();
    }
}

// 生產get請求的產品
const simpleGetRequestIns = GetRequestFactory.createSimpleRequest();
simpleGetRequestIns.setUrl('https://xxx'); // 設置get請求的url
simpleGetRequestIns.setParams({id: 'xxx'}); // 設置get請求的參數
simpleGetRequestIns.request();
const normalGetRequestIns = GetRequestFactory.createNormalRequest();
normalGetRequestIns.setUrl('https://xxx'); // 設置get請求的url
normalGetRequestIns.setParams({id: 'xxx'}); // 設置get請求的參數
normalGetRequestIns.request();

// 生產post請求的產品
const simplePostRequestIns = PostRequestFactory.createSimpleRequest();
simplePostRequestIns.setUrl('https://xxx'); // 設置get請求的url
simplePostRequestIns.setParams({id: 'xxx'}); // 設置get請求的參數
simplePostRequestIns.request();
const normalPostRequestIns = PostRequestFactory.createNormalRequest();
normalPostRequestIns.setUrl('https://xxx'); // 設置get請求的url
normalPostRequestIns.setParams({id: 'xxx'}); // 設置get請求的參數
normalPostRequestIns.request();

經過上面的代碼,咱們能夠看到,抽象工廠模式之於工廠模式的不一樣就是在工廠模式的基礎上,對產品也進行了一層抽象,從而實現了一個實體工廠也能生產多個產品的功能。

「抽象工廠模式」的好處就是:

  • 易於交換產品系列,咱們只須要初始化工廠,就能夠隨意切換生產的產品
  • 它讓具體的建立實例過程和客戶端分離,客戶端經過他們的抽象接口操縱實例,產品的具體類名也被具體工廠的實現分離,不會出如今客戶代碼中。

「抽象工廠模式」有五大要素:

  • 抽象工廠
  • 實體工廠
  • 抽象模具
  • 模具
  • 實體產品

參考

大話設計模式 - 程傑

工廠模式與抽象工廠模式的區別 - 賈不假

我的博客

北落師門的博客

相關文章
相關標籤/搜索