单例模式,适用于对象唯一的情景(设计模式与开发实践 P4)

文章目录

    • 单例模式
    • 实现
    • 代理单例
    • 惰性单例

上一章后续的内容是关于 JS 函数闭包的,考虑很多读者已经有了闭包基础或者希望通过实战理解,遂跳过上一章直接开始设计模式篇~

需要注意的是,代码部分仅供参考,主要关注的内容是设计模式的思想和运用,结合到自己的实战中才是最好的

单例模式

单例模式的定义是:保证一个类只有一个实例,并提供一个访问他的全局访问点

例如:线程池,全局缓存,登陆窗口(无论你点击多少次,窗口都只会创建一个)

实现

实现起来并不复杂,只需要创建一个变量来标识是否已经为某个类创建过对象,如果已经创建了,那就直接返回之前创建的对象~

const Singleton = {
  instance: null,
  getInstance: function () {
    if (!this.instance) {
      this.instance = {
        // 在这里定义单例的属性和方法
        name: "Singleton Instance",
        sayHello: function () {
          console.log("Hello from Singleton!");
        },
      };
    }
    return this.instance;
  },
};

// 使用示例
const instance1 = Singleton.getInstance();
console.log(instance1.name); // 输出: Singleton Instance
instance1.sayHello(); // 输出: Hello from Singleton!

const instance2 = Singleton.getInstance();
console.log(instance2.name); // 输出: Singleton Instance

console.log(instance1 === instance2); // 输出: true

方便结合理解,我们加入一个静态型面向对象的语言 C# 来看:

public class Singleton
{
    private static Singleton instance;

    // 私有构造函数,防止外部实例化
    private Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }

    // 在这里定义单例的其他属性和方法
    public string Name { get; set; }

    public void SayHello()
    {
        Console.WriteLine("Hello from Singleton!");
    }
}

代理单例

上面的代码有一个问题,你会发现 JS 部分中,一部分代码用来保证单例不重复创建,另一部分代码用来创建单例对象,显然这不是一个好的做法,如果某一天我们要改写这个单例代码,无疑会使代码变得复杂,所以引入 代理 单例模式

通过这样就使得 Singleton 成为了一个普通的类,和 Proxy 组成了单例模式!

var Singleton = function () {
  this.name = "Singleton Instance";
};

Singleton.prototype.sayHello = function () {
  console.log("Hello from Singleton!");
};

const SingletonProxy = (function () {
  var instance;
  return function () {
    if (!instance) {
      instance = new Singleton();
    }
    return instance;
  };
})();

// 使用示例
var proxyInstance1 = new SingletonProxy();
var proxyInstance2 = new SingletonProxy();

console.log(proxyInstance1.name);
console.log(proxyInstance2.name);

同样还有 C# 版的:

private class Singleton
{
    private Singleton()
    {
        // 构造函数
    }
}

public class SingletonProxy
{
    private Singleton proxyInstance;
    
    public Singleton GetInstance()
    {
        if (proxyInstance == null)
        {
            proxyInstance = Singleton.Instance;
        }
        return proxyInstance;
    }
}

惰性单例

上面的代码已经实现了惰性单例模式:只有调用的时候才实现对象的初始化,即这一段:

public Singleton GetInstance()
{
    if (proxyInstance == null)
    {
        proxyInstance = Singleton.Instance;
    }
    return proxyInstance;
}

这样使得资源和配置更灵活,且线程安全~

你可能感兴趣的:(设计模式,单例模式,设计模式,javascript)