前言:设计模式作为编程实践中很重要的一个部分,能为我们的代码提供更优雅简介的实现方式。模式作为已经被验证了的解决方案,具有很强的复用性和表达力。下面我们将分篇章依次介绍 JavaScript 中存在的 20 多种设计模式
单例模式的介绍
单例模式限制了类的实例化次数为 1 次。从经典的意义上来说,Singleton 模式,在该实例不存在的情况下,可以通过一个方法创建一个类来创建类的新实例,如果实力已经存在,它会简单地返回该对象的引用。Singleton 模式不同于静态类( 或对象 ),我们可以推迟其初始化。( 这通常是因为他们需要一些信息,而这些信息在初始化期间可能无法获得 )
单例模式的适用场景
- 当类只能有一个实例,且有一个公共的访问点可以访问它
- 该唯一的实例应该是通过子类化可扩展的,并且用户可以无需修改代码就可以使用一个扩展的实例
对象字面量实现单例模式
1 2 3 4 5 6
| var mySingleton = { property1: "something", method1: function () { console.log('mySingleton method 1'); } };
|
延迟执行版单例模式实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| var mySingleton = (function () {
var instance;
function init() { function privateMethod() { console.log('I am private'); }
var privateVariable = 'Im also private'; var privateRandomNumber = Math.random();
return { publicProperty: "I am also public", getRandomNumber: function () { return privateRandomNumber; } } }
return { getInstance: function () { if (!instance) instance = init(); return instance; } } })();
var singleA = mySingleton.getInstance(); var singleB = mySingleton.getInstance();
console.log(singleA.getRandomNumber() === singleB.getRandomNumber());
|
上面 mySingleton
类直到执行 var singleA = mySingleton.getInstance();
才会被实例化,在此之前不占用内存或 cpu 资源。由于是单例模式,故而 singleA 和 singleB 指向同一个 mySingleton
类的实例,故而返回 true。
单例模式的延迟执行可以让类在被使用到之前,不使用资源和内存,(在 C++ 中,Singleton 模式负责隔绝动态初始化顺序的不可预知性,将控制权归还给程序员)
单例模式可以用于系统间各种模式的通信协调上
当系统中需要一个对象来协调其他对象时,单例模式将起到很大的作用,下面代码是一个简单的最佳实践:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| var SingletonTester = (function () {
function Singleton(options) { options = options || {}; this.name = "singletonTester"; this.pointX = options.pointX || 0; this.pointY = options.pointY || 0; }
var instance;
var _static = { name: "singletonTester", getInstance: function (options) { if (!instance) instance = new Singleton(options); return instance; } };
return _static;
})();
var singletonTest = SingletonTester.getInstance({ pointX: 5 });
console.log(singletonTest.pointX);
|
我们可以使用单例 SingletonTester 来在各个模式和函数间共享同一个 Singleton 类的实例,来共享该实例的 name, pointX, pointY 等信息。
本文学习引用自 [JavaScript 设计模式] 一书,感谢作者 Addy Osmani 和译者徐涛的贡献。