核心思想:把创建实例对象和管理单例的职责分别放置在两个方法里,可灵活选择是否使用单例
4.1 实现单例模式
类似于static方法获取单例
和后面的通用惰性单例相似,(这里是标准的创建对象的实例,后面例子是一般情况下创建一个普通对象)
- 创建实例对象:执行构造函数
管理单例:getInstance静态方法
class Singleton {instance;constructor(name) {this.name = name;}static getInstance(name) {return this.instance || this.instance = new Singletom(name);}}
var a = Single.getInstance('a');var b = Single.getInstance('b');
4.2 透明的单例模式
- 可以用new的方式
- 用闭包的方式返回构造函数,但是构造函数内做了两件事
创建实例和管理单例没有分开,如果这个类以后要从单例类变为普通类呢?
var CreateDiv = (function () {var instance;var CreateDiv = function (html) {if (instance) {return instance;}this.html = html;this.init();return instance = this;}CreateDiv.prototype.init = function () {// ...}return CreateDiv;})();
var a = new CreateDiv('a');var b = new CreateDiv('b');
4.3 用代理实现单例模式
原类不变,作为普通类,具体实现使用代理类控制
// 这也是缓存代理模式var ProxySingletomCreateDiv = (function () {var instance;return function (html) {if (!instance) {instance = new CreateDiv('html');}return instance;}});
// 这里其实用new是多余的var a = new ProxySingletomCreateDiv('a');var b = new ProxySingletomCreateDiv('b');
4.4 JavaScript中的单例模式
这一节我觉得讲得有点鸡肋。
不是创建类,一个变量就是一个单例。 杜绝全局变量,用命名空间、闭包。
4.5 惰性单例,通用的惰性单例
把创建实例对象和管理单例的职责分别放置在两个方法里
- 如果不用单例,就直接调用创建实例方法;
如果要用单例,就用getSingle方法传入创建实例的方法
var getSingle = function (fn) {var instance;return function () {return instance || (instance = fn.apply(this.arguments))}}
```typescript var createLoginLayer = function () {// …} var loginLayer = getSingle(createLoginLayer); var loginLayerAnother = getSingle(createLoginLayer);
var createIframe = function () {// … var iframe = getSingle(createIframe); var iframeAnother = getSingle(createIframe);
<a name="BoHED"></a># 扩展 Java的单例模式<a name="Yq5kr"></a>## 静态内部类实现单例模式> 当 Singleton 类加载时,静态内部类 SingletonHolder 没有被加载进内存。只有当调用 getUniqueInstance()方法从而触发 SingletonHolder.INSTANCE 时 SingletonHolder 才会被加载,此时初始化 INSTANCE 实例,并且 JVM 能确保 INSTANCE 只被实例化一次。> 这种方式不仅具有延迟初始化的好处,而且由 JVM 提供了对线程安全的支持。> 参考:[https://javaguide.cn/java/basis/java-keyword-summary/#%E9%9D%99%E6%80%81%E5%86%85%E9%83%A8%E7%B1%BB](https://javaguide.cn/java/basis/java-keyword-summary/#%E9%9D%99%E6%80%81%E5%86%85%E9%83%A8%E7%B1%BB)```javapublic class Singleton {//声明为 private 避免调用默认构造方法创建对象private Singleton() {}// 声明为 private 表明静态内部该类只能在该 Singleton 类中被访问private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getUniqueInstance() {return SingletonHolder.INSTANCE;}}
