1.两数之和-力扣
744 2023-04-03 03:31:44
每当我听到有人讨论设计模式时,我听到最多的概念好像就是「工厂模式」,他就像是背单词时候的「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();
通过上面的代码,我们可以看到,抽象工厂模式之于工厂模式的不同就是在工厂模式的基础上,对产品也进行了一层抽象,从而实现了一个实体工厂也能生产多个产品的功能。
「抽象工厂模式」的好处就是:
「抽象工厂模式」有五大要素:
创建型模式: 创建型模式抽象了实例化的过程,他们帮助一个系统独立于如何创建、组合和表示它的那些对象。创建型模式都会将关于该系统使用哪些具体的类的信息封装起来。允许客户用结构和功能差别很大的「产品」对象配置一个系统。配置可以是静态的,即在编译时指定,也可以是动态的,就是运行时再指定。
大话设计模式 - 程杰
工厂模式与抽象工厂模式的区别 - 贾不假
北落师门的博客