核心思想:把创建实例对象和管理单例的职责分别放置在两个方法里,可灵活选择是否使用单例

4.1 实现单例模式

类似于static方法获取单例
和后面的通用惰性单例相似,(这里是标准的创建对象的实例,后面例子是一般情况下创建一个普通对象)

  1. 创建实例对象:执行构造函数
  2. 管理单例:getInstance静态方法

    1. class Singleton {
    2. instance;
    3. constructor(name) {
    4. this.name = name;
    5. }
    6. static getInstance(name) {
    7. return this.instance || this.instance = new Singletom(name);
    8. }
    9. }
  1. var a = Single.getInstance('a');
  2. var b = Single.getInstance('b');

4.2 透明的单例模式

  • 可以用new的方式
  • 用闭包的方式返回构造函数,但是构造函数内做了两件事
  • 创建实例和管理单例没有分开,如果这个类以后要从单例类变为普通类呢?

    1. var CreateDiv = (function () {
    2. var instance;
    3. var CreateDiv = function (html) {
    4. if (instance) {
    5. return instance;
    6. }
    7. this.html = html;
    8. this.init();
    9. return instance = this;
    10. }
    11. CreateDiv.prototype.init = function () {
    12. // ...
    13. }
    14. return CreateDiv;
    15. })();
    1. var a = new CreateDiv('a');
    2. var b = new CreateDiv('b');

    4.3 用代理实现单例模式

    原类不变,作为普通类,具体实现使用代理类控制

    1. // 这也是缓存代理模式
    2. var ProxySingletomCreateDiv = (function () {
    3. var instance;
    4. return function (html) {
    5. if (!instance) {
    6. instance = new CreateDiv('html');
    7. }
    8. return instance;
    9. }
    10. });
    1. // 这里其实用new是多余的
    2. var a = new ProxySingletomCreateDiv('a');
    3. var b = new ProxySingletomCreateDiv('b');

    4.4 JavaScript中的单例模式

    这一节我觉得讲得有点鸡肋。

    不是创建类,一个变量就是一个单例。 杜绝全局变量,用命名空间、闭包。

4.5 惰性单例,通用的惰性单例

把创建实例对象和管理单例的职责分别放置在两个方法里

  1. 如果不用单例,就直接调用创建实例方法;
  2. 如果要用单例,就用getSingle方法传入创建实例的方法

    1. var getSingle = function (fn) {
    2. var instance;
    3. return function () {
    4. return instance || (instance = fn.apply(this.arguments))
    5. }
    6. }

    ```typescript var createLoginLayer = function () {// …} var loginLayer = getSingle(createLoginLayer); var loginLayerAnother = getSingle(createLoginLayer);

var createIframe = function () {// … var iframe = getSingle(createIframe); var iframeAnother = getSingle(createIframe);

  1. <a name="BoHED"></a>
  2. # 扩展 Java的单例模式
  3. <a name="Yq5kr"></a>
  4. ## 静态内部类实现单例模式
  5. > 当 Singleton 类加载时,静态内部类 SingletonHolder 没有被加载进内存。只有当调用 getUniqueInstance()方法从而触发 SingletonHolder.INSTANCE 时 SingletonHolder 才会被加载,此时初始化 INSTANCE 实例,并且 JVM 能确保 INSTANCE 只被实例化一次。
  6. > 这种方式不仅具有延迟初始化的好处,而且由 JVM 提供了对线程安全的支持。
  7. > 参考:[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)
  8. ```java
  9. public class Singleton {
  10. //声明为 private 避免调用默认构造方法创建对象
  11. private Singleton() {
  12. }
  13. // 声明为 private 表明静态内部该类只能在该 Singleton 类中被访问
  14. private static class SingletonHolder {
  15. private static final Singleton INSTANCE = new Singleton();
  16. }
  17. public static Singleton getUniqueInstance() {
  18. return SingletonHolder.INSTANCE;
  19. }
  20. }