面试题之几种常见设计模式
单例模式:
单例模式很常用,比如全局缓存、全局状态管理等等这些只需要一个对象,就可以使用单例模式;
单例模式的核心就是保证全局只有一个对象可以访问。因为JS是门无类的语言,所以别的语言实现单例的方式并不能嵌入 JS 中,我们只需要用一个变量确保实例只创建一次就行,以下是如何实现单例模式的例子:
在 Vuex 源码中,也可以看到单例模式的使用,它是通过一个外部变量来控制只安装一次Vuex
适配器模式:
适配器用来解决两个接口不兼容的情况,不需要改变已有的接口,通过包装一层的方式实现两个接口的正常协作。
在 Vue 中,我们其实经常使用到适配器模式。比如父组件传递给子组件一个时间戳属性,组件内部需要将时间戳转为正常的日期显示,一般会使用 computed 来做转换这件事情,这个过程就使用到了适配器模式;
装饰模式:
装饰模式不需要改变已有接口,作用是给对象添加功能。举个栗子:我们经常需要给手机戴个保护套防摔一样,不改变手机本身,给手机添加了保护套提供了防摔功能;
在 React 中,装饰模式其实随处可见,如下所示:
代理模式:
代理是为了控制对对象的访问,不让外部直接访问到对象。在现实生活中,也有很多代理的场景。比如你需要买一件国外的产品,这时候你可以通过代购来购买产品。
在实际代码中其实代理的场景很多,事件代理就是使用了代理模式:
发布-订阅模式:
发布-订阅模式也叫做观察者模式。通过一对一或者一对多的依赖关系,当对象发生改变时,订阅方都会收到通知。在现实生活中,也有很多类似场景。举个生活中的例子:比如我需要在购物网站上购买一个产品,但是发现该产品目前处于缺货状态,这时候我可以点击有货通知的按钮,让网站在产品有货的时候通过短信通知我。
在实际代码中其实发布-订阅模式也很常见,比如我们点击一个按钮触发了点击事件就是使用了该模式:
可以套用上面的例子:
在 vue 中,实现响应式也是使用了该模式。对于需要实现响应式的对象来说,在 get 的时候会进行依赖收集,当改变了对象的属性时,就会触发派发更新;
外观模式:
外观模式提供了一个接口,隐藏了内部的逻辑,更加方便外部调用。
举个例子来说:
如上代码中 tomallList 方法封装了各种场景下的代码处理方式,外部事件的实现只要处理了这一块的代码即可;