单例模式简介
Point 1.单例模式的作用
- 节省不必要的内存开销
- 屏蔽对象创建的复杂性
- 避免了类在外部被实例化
Point 2.单例模式的特性
- 单例类只能有一个实例
- 单例类必须自己创建自己的唯一实例
- 单例类必须给所有其他对象提供这一实例
Point 3.单例模式使用场景
只有一个实例的对象或只需要一个实例的对象
静态语言中的单例模式
静态类型语言需要定义单例类,封装构造方法,并提供返回单例对象接口
1.懒加载形式(需要额外去实现线程安全)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Singleton { private Singleton() {} private static Singleton single=null; public static Singleton getInstance() { if (single == null) { single = new Singleton(); } return single; }
public static synchronized Singleton getInstanceSafe() { if (single == null) single = new Singleton(); return single; } }
|
2.直接实例化形式(线程安全)
1 2 3 4 5 6 7
| public class Singleton1 { private Singleton1() {} private static final Singleton1 single = new Singleton1(); public static Singleton1 getInstance() { return single; } }
|
3.双重校验形式(基本线程安全)
1 2 3 4 5 6 7 8 9 10
| public static Singleton getInstance() { if (instance == null) { synchronized(Singleton.class) { if (instance == null) instance = new Singleton(); } } return instance; }
|
产生线程不安全的原因, 看完后如提壶灌顶
动态语言中的单例模式
JS中无需创建单独的单例”类”的概念,函数作为一等对象,利用高阶函数可以实现抽象的单例工厂
- 全局变量 JS中可以使用带命名空间的全局变量”实现”单例模式
- 闭包实现的单例工厂(重点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var getSingleton = function(fn) { var singleton = null; return function(){ return singleton || (singleton = fn.apply(this,arguments)); } }
var A = function(){ return { }; }
var singletonA = getSingleton(singleObject);
var singleInstance1 = singletonA(); var singleInstance2 = singletonA(); console.log(singleInstance1 === singleInstance2);
|
Summary
- Java,C#等静态语言需要创建单例类实现,也可以利用反射机制创建单例,需要考虑线程安全问题.
- js中也可以采用静态语言的思维创建单例类, 添加一个生成单例的函数获取单例
- js闭包的特性提供了更加灵活和抽象的解决方案, 并且单线程的js无需考虑线程安全问题.