介绍
在所有设计模式中,最基础同时也非常实用的一类就是单例模式了。单例模式,顾名思义,指的是在此种设计模式下,整个系统将只会构建一次实例,接下来每一次的新的生成都视为对第一次生成实例的引用。
其实,单例模式在我们的项目中运用的十分广泛,例如浏览器的全局变量 window 就是一个例子,所有声明的全局变量都要挂靠在 window 下,并且 window 变量只生成一次,全局都能够调用。再比如一些一些需要保持唯一性的组件,例如顶部提示框、对话框、抽屉组件等等,也都可以用单例模式来解决。
基础实现
接下来我们尝试着来实现一下单例模式的构造函数。假设我们现在想实现一个单例的顶部提示框组件,简单展示如下:
1 | class Notification { |
为了实现所需的目标,我们需要为该类增添一个获取单例实例的函数 getInstance。先定义一个标志位记录生成的实例,每次调用时检查,若未实例化则生成一个实例,否则返回之前生成实例的引用。
1 | Notification.getInstance = function(...args) { |
这样就实现了这个组件的单例化。
能不能更通用
上面这个例子能够实现所需要的目标,但是代码过于耦合,且不方便复用。我们可以考虑使用更通用的方法来实现这一目标。比如我们可以将单例逻辑抽离出来,在原组件外层包裹一个用于生成单例的函数,返回一个功能相同,但拥有单例功能的新组件。
1 | const Singleton = function(Class) { |
这样就实现了单例逻辑与实际功能组件的解耦。这里实际上用到了装饰器模式的一些思想,关于装饰器模式我们留到下一节说。