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();

经过上面的代码,咱们能够看到,抽象工厂模式之于工厂模式的不一样就是在工厂模式的基础上,对产品也进行了一层抽象,从而实现了一个实体工厂也能生产多个产品的功能。

「抽象工厂模式」的好处就是:

  • 易于交换产品系列,咱们只须要初始化工厂,就能够随意切换生产的产品
  • 它让具体的建立实例过程和客户端分离,客户端经过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出如今客户代码中。

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

  • 抽象工厂
  • 实体工厂
  • 抽象模具
  • 模具
  • 实体产品

参考

大话设计模式 - 程杰

工厂模式与抽象工厂模式的区别 - 贾不假

我的博客

北落师门的博客

相关文章
相关标签/搜索