玩转设计模式(一)

461 阅读3分钟

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」。

序言

随着对编程的理解越来越深,看的开源项目越来越多,越发的感到设计模式的重要性。在此之前,只对观察者模式,发布订阅者模式有一定了解,但是觉得很有必要认识一下所有的常用设计模式,以便于开扩自己的编程思维,这个系列预计会有25篇左右,目的就是为了补实基础,顺便拿下十一月的更文奖励,今天的第一篇,我们先来聊聊JavaScript中的一些有趣现象。

什么是设计?

当我门还是初学者的时候,往往会进行如下的编码

//功能:请求用户的一些信息function requestUserName(){
  //1. 请求用户名
}
function requestUseSex(){
  //2. 请求用户性别
}
function requestUserAge(){
    //3. 请求用户年龄
}

这种编码会造成一个问题,这些都是全局函数方法,如果有人用了相同的名字,那么方法就会被覆盖,那么要如何解决这种隐患呢?我们可以使用对象来收编方法:

let requestUserInfo = {
  getName : function requestUserName(){
    //1. 请求用户名
  },
  getSex : function requestUseSex(){
      //2. 请求用户性别
    },
  getAge : function requestUserAge(){
      //3. 请求用户年龄
    }
}

我们将这些方法集中在一个对象中,这样避免了方法覆盖的问题,我们使用的话需要requestUserInfo.getName()这样使用,但是别人要用你的方法的时候,却不好使用,因为通过new 创建的对象并不会继承这些方法,聪明的小伙伴应该想到了,没错我们可以使用类!

let requestUserInfo = function(){
  this.getName = function requestUserName(){
    //1. 请求用户名
  },
  this.getSex = function requestUseSex(){
      //2. 请求用户性别
    },
  this.getAge = function requestUserAge(){
      //3. 请求用户年龄
    }
}

我们要使用的只需要创建实例就可以了

let a = new requestUserInfo()
a.getName()
a.getSex()
a.getAge()

还能怎么改进?

使用原型挂载方法

我们上例中的类是通过this进行定义的,这样会造成一个问题,就是每次实例化的时候都要频繁的操作类的this。所以我们可以直接把方法挂载到原型上。

let requestUserInfo = function(){}
  requestUserInfo.prototype.getName = function requestUserName(){
    //1. 请求用户名
  },
  requestUserInfo.prototype.getSex = function requestUseSex(){
      //2. 请求用户性别
    },
  requestUserInfo.prototype.getAge = function requestUserAge(){
      //3. 请求用户年龄
    }

然后我们又发现,我们反复的requestUserInfo.prototype,我们做出以下的优化:

let requestUserInfo = function(){}
  requestUserInfo.prototype={
   getName :function requestUserName(){
    //1. 请求用户名
  },
    getSex : function requestUseSex(){
      //2. 请求用户性别
    },
    getAge : function requestUserAge(){
      //3. 请求用户年龄
    }
  }

使用方法

let a = new requestUserInfo()
a.getName()
a.getSex()
a.getAge()

简化操作之链式调用

我们发现上面使用的话,得频繁的使用实例对象a,我们都知道JavaScript中有链式调用,那么如何进行链式调用呢,秘诀就是方法的返回值得是当前的this

let requestUserInfo = function(){}
  requestUserInfo.prototype={
   getName :function requestUserName(){
    //1. 请求用户名
     return this
  },
    getSex : function requestUseSex(){
      //2. 请求用户性别
     return this
    },
    getAge : function requestUserAge(){
      //3. 请求用户年龄
      return this
    }
  }

现在使用的话就很简单啦

let a = new requestUserInfo()
a.getName().getSex().getAge()

小结

一个最基础的函数编码竟然能玩出这么多花样,不得不佩服前人们的智慧,从最开始解决同名覆盖,再到优化构建,再到优化使用,一层层的设计应接不暇,并且这些思想可以应用到工作中,生活中,给我们的工作带来极大的帮助,而我们接下里学习的设计模式,就是将一个个优秀的设计思想,提炼的结晶。