1、介绍javascript
每当我听到有人讨论设计模式时,我听到最多的概念好像就是「工厂模式」,他就像是背单词时候的「abandon」,它易于理解且常常用到,因此我也将它做为学习「设计模式」的第一步。前端
咱们都知道,工厂模式是为了建立对象而存在的(主要是听到的太多了~)。对象是一个系统的基石,咱们编写的功能均可以抽象成由一个个对象组合而成,请求是由一个个XmlHttpRequest对象执行的、页面由一个个DOM节点对象堆砌而成等等。咱们在前端框架之中每每会对请求做一层层的封装(好比咱们会在JQuery.ajax、axios之上再封装一层),那咱们在生成这些对象的时候,会发现他们都有着类似之处,就像是由工厂生产出来的一个个产品,那咱们封装的过程其实就和「工厂模式」很相近了。java
工厂模式属于「建立型模式」的一种,与之相关的有:简单工厂模式、工厂模式和抽象工厂模式。ios
简单工厂模式能够理解为「一家工厂根据不一样的模具来生产产品」的模式,以下举例: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
工厂模式是在简单工厂模式之上作了优化处理以后造成一种模式,咱们先看有关于工厂模式的代码设计模式
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公司,还不如复制一个抽象公司,而后专事专作。
上面的例子就是为了帮助咱们理解「简单工厂模式」和「工厂模式」的区别的,那咱们何时用哪一种模式呢?个人理解就是:
其实上面说的也关乎到设计模式中的一个原则——「开闭原则」。
再回到「工厂模式」之上,咱们能够看到工厂模式的特色就是:
「工厂模式」包含四大要素:
此时确定有朋友想到了一个问题:「现实中咱们也并非全部的工厂都只生产一类产品,牛奶工厂能够生产纯牛奶、酸奶等等」,这就是咱们提到的抽象工厂模式了。示例代码以下
// 抽象工厂 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();
经过上面的代码,咱们能够看到,抽象工厂模式之于工厂模式的不一样就是在工厂模式的基础上,对产品也进行了一层抽象,从而实现了一个实体工厂也能生产多个产品的功能。
「抽象工厂模式」的好处就是:
「抽象工厂模式」有五大要素:
大话设计模式 - 程杰