创建型-单例模式
场景
在一个系统中可能只有一个数据库连接、一个网络连接或一个唯一的配置文件。在这些情况下,使用单例模式可以确保系统中只有一个实例,从而避免问题的发生。单例模式还可以用于对象缓存、日志系统和对象池等。需要注意的是,使用单例模式并不是解决所有问题的万能药,过度使用单例模式可能会导致软件设计的不灵活,并且难以测试和维护。因此,在使用单例模式时要谨慎考虑。
实现
使用单例模式对localStorage 进行封装。实现方法 setItem(key,value) 和 getItem(key)。
静态方法版
// 定义Storageclass Storage { static getInstance() { // 判断是否已经new过1个实例 if (!Storage.instance) { // 若这个唯一的实例不存在,那么先创建它 Storage.instance = new Storage() } // 如果这个唯一的实例已经存在,则直接返回 return Storage.instance } getItem (key) { return localStorage.getItem(key) } setItem (key, value) { return localStorage.setItem(key, value) }}
const storage1 = Storage.getInstance()const storage2 = Storage.getInstance()
storage1.setItem('name', '李雷')// 李雷storage1.getItem('name')// 也是李雷storage2.getItem('name')
// 返回truestorage1 === storage2闭包版
// 先实现一个基础的StorageBase类,把getItem和setItem方法放在它的原型链上function StorageBase () {}StorageBase.prototype.getItem = function (key){ return localStorage.getItem(key)}StorageBase.prototype.setItem = function (key, value) { return localStorage.setItem(key, value)}
// 以闭包的形式创建一个引用自由变量的构造函数const Storage = (function(){ let instance = null return function(){ // 判断自由变量是否为null if(!instance) { // 如果为null则new出唯一实例 instance = new StorageBase() } return instance }})()
// 这里其实不用 new Storage 的形式调用,直接 Storage() 也会有一样的效果const storage1 = new Storage()const storage2 = new Storage()
storage1.setItem('name', '李雷')// 李雷storage1.getItem('name')// 也是李雷storage2.getItem('name')
// 返回truestorage1 === storage2优点
单例模式可以保证系统中有且仅有一个实例,降低了系统的复杂度; 单例模式可以控制对象的创建,提供访问入口; 单例模式可以避免对资源的多重占用。
总结
保证一个类仅有一个实例,并提供一个访问它的全局访问点,这样的模式就叫做单例模式。