一、介绍

每当我听到有人探讨设计模式时,我听到最多的概念如同就是「工厂模式」,他就像是背单词时候的「abandon」,它易于了解且常常用到,所以我也将它作为学习「设计模式」的第一步。

咱们都晓得,工厂模式是为了创建对象而存在的(次要是听到的太多了~)。对象是一个零碎的基石,咱们编写的性能都能够形象成由一个个对象组合而成,申请是由一个个XmlHttpRequest对象执行的、页面由一个个DOM节点对象堆砌而成等等。咱们在前端框架之中往往会对申请作一层层的封装(比方咱们会在JQuery.ajax、axios之上再封装一层),那咱们在生成这些对象的时候,会发现他们都有着相似之处,就像是由工厂生产进去的一个个产品,那咱们封装的过程其实就和「工厂模式」很相近了。

工厂模式属于「创立型模式」的一种,与之相干的有:简略工厂模式工厂模式形象工厂模式

二、简略工厂模式

简略工厂模式能够了解为「一家工厂依据不同的模具来生产产品」的模式,如下举例:

// 工厂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申请的urlgetRequestInstance.setParams({id: 'xxx'}); // 设置get申请的参数getRequestInstance.request();// 工厂生产处post申请的产品const postRequestInstance = SimpleRequestFactory.createRequest('post');postRequestInstance.setUrl('https://xxx'); // 设置post申请的urlpostRequestInstance.setParams({id: 'xxx'}); // 设置post申请的参数getRequestInstance.request();

以上就是简略工厂模式运行模式,利用这种形式,咱们就能够依据不同申请的须要,来一直生产request申请对象,咱们并不需要关怀request的实例对象是怎么生成的,咱们只须要失去它、应用它即可。

所以「简略工厂模式」的特点就是:

  • 咱们只须要晓得咱们要生产的产品的名称即可
  • 咱们不须要晓得产品怎么来的,咱们只须要晓得产品怎么用

由下面的代码咱们也能看出,简略工厂模式是具备三大因素的:

  • 工厂类:由它依据模具来生产产品
  • 模具类(抽象类产品):它是所有产品的基石,咱们依据它们来失去用户应用的产品
  • 产品对象:简略工厂模式的创立指标,用户最终应用的就是具体的产品对象

三、工厂模式

工厂模式是在简略工厂模式之上做了优化解决之后造成一种模式,咱们先看有对于工厂模式的代码

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申请的urlgetRequestIns.setParams({id: 'xxx'}); // 设置get申请的参数getRequestIns.request();// 生产post申请的产品const postRequestIns = PostRequestFactory.createRequest();postRequestIns.setUrl('https://xxx'); // 设置get申请的urlpostRequestIns.setParams({id: 'xxx'}); // 设置get申请的参数postRequestIns.request();// 生产put申请的产品const putRequestIns = PutRequestFactory.createRequest();putRequestIns.setUrl('https://xxx'); // 设置get申请的urlputRequestIns.setParams({id: 'xxx'}); // 设置get申请的参数putRequestIns.request();

由下面的代码能够看出,咱们把每一种申请的生产工厂都独立进去了,看似没有简略工厂模式不便,然而咱们能够在生存之中找到例子辅助了解。

比方咱们A公司是一家生产饮品的公司,咱们最开始有一条生产线专门生产矿泉水,咱们叫「XX山泉」,起初咱们发现矿泉水做的不错,咱们想多做一些产品,如「XX AD钙奶」和「XX 纯牛奶」,那咱们应该怎么做呢?这时咱们可能依据生存中看到的例子,能够想到,咱们只有照搬A公司的根底部门(如行政),再成立几家公司,别离生产「XX AD钙奶」和「XX 纯牛奶」即可。那咱们为什么不在A公司的根底上一直裁减生产线呢?因为一旦生产线越来越多,治理就越来越简单,咱们须要一直地折腾A公司,还不如复制一个形象公司,而后专事专做。

下面的例子就是为了帮忙咱们了解「简略工厂模式」和「工厂模式」的区别的,那咱们什么时候用哪种模式呢?我的了解就是:

  • 如果零碎简略,须要生成的对象类型可数,就用「简略工厂模式」
  • 如果零碎存在扩大的可能性,且咱们无奈预计将来扩大的规模,就用「工厂模式」

其实下面说的也关乎到设计模式中的一个准则——「开闭准则」

再回到「工厂模式」之上,咱们能够看到工厂模式的特点就是:

  • 合乎「开闭准则」,易于扩大
  • 会减少零碎的复杂度

「工厂模式」蕴含四大因素:

  • 形象工厂:形象工厂不是一家理论的公司,然而他领有所有公司共同点
  • 实体工厂:实体工厂负责生产具体的产品
  • 模具(形象产品):咱们依据模具来生产产品
  • 实体产品:用户最终失去并应用实体产品

三、形象工厂模式

此时必定有敌人想到了一个问题:「事实中咱们也并不是所有的工厂都只生产一类产品,牛奶工厂能够生产纯牛奶、酸奶等等」,这就是咱们提到的形象工厂模式了。示例代码如下

// 形象工厂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申请的urlsimpleGetRequestIns.setParams({id: 'xxx'}); // 设置get申请的参数simpleGetRequestIns.request();const normalGetRequestIns = GetRequestFactory.createNormalRequest();normalGetRequestIns.setUrl('https://xxx'); // 设置get申请的urlnormalGetRequestIns.setParams({id: 'xxx'}); // 设置get申请的参数normalGetRequestIns.request();// 生产post申请的产品const simplePostRequestIns = PostRequestFactory.createSimpleRequest();simplePostRequestIns.setUrl('https://xxx'); // 设置get申请的urlsimplePostRequestIns.setParams({id: 'xxx'}); // 设置get申请的参数simplePostRequestIns.request();const normalPostRequestIns = PostRequestFactory.createNormalRequest();normalPostRequestIns.setUrl('https://xxx'); // 设置get申请的urlnormalPostRequestIns.setParams({id: 'xxx'}); // 设置get申请的参数normalPostRequestIns.request();

通过下面的代码,咱们能够看到,形象工厂模式之于工厂模式的不同就是在工厂模式的根底上,对产品也进行了一层形象,从而实现了一个实体工厂也能生产多个产品的性能。

「形象工厂模式」的益处就是:

  • 易于替换产品系列,咱们只须要初始化工厂,就能够随便切换生产的产品
  • 它让具体的创立实例过程和客户端拆散,客户端通过他们的形象接口操纵实例,产品的具体类名也被具体工厂的实现拆散,不会呈现在客户代码中。

「形象工厂模式」有五大因素:

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

参考

大话设计模式 - 程杰

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

集体博客

北落师门的博客