什么是单例模式?怎么生成单例类? - 1/14

简介: 什么是单例模式?怎么生成单例类? - 1/14

什么是单例模式?怎么生成单例类? - 1/14


单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。比如线程池、全局缓存、浏 览器中的 window 对象等。

实现单例模式

实现一个标准的单例模式,其实用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象。

v1.0,直觉思路

直接按照思路写

let instance;
function X(name) {
  if (instance) {
    return instance;
  }
  this.name = name;
  instance = this;
}
var a = new X("a");
var b = new X("b");
// true
console.log(a === b);

v2.0,让变量内部化

使用闭包让 instance 不暴露在全局,返回的函数是真正的类

// 其实就是把上面的代码用个自执行函数包起来,末了返回上面X的实体内容
var X = (function() {
  let instance;
  return function(name) {
    if (instance) {
      return instance;
    }
    this.name = name;
    instance = this;
  };
})();
var a = new X("a");
var b = new X("b");
console.log(a === b);

v3.0,升级加个代理类

上面代码中,X 的构造函数实际上负责了两件事情。

  • 创建对象
  • 保证只有一个对象。

这违反了“单一职责原则”的概念,所以我们拆开试试,普通的类就是普通的类,如果需要单例的类,创建一个新类,这个新类就是一个代理类。

// 普通的X类
function X(name) {
  this.name = name;
}
// 代理类,实际返回的是X的实例
var X_Proxy = (function() {
  let instance;
  return function(...args) {
    if (instance) {
      return instance;
    }
    // 其实就是把上个版本的这里改成生成的实例而已啦
    instance = new X(...args);
    // !!!注意,这里返回的是X的实例
    return instance;
  };
})();
var a = new X_Proxy("a");
var b = new X_Proxy("b");
console.log(a === b);

v3.1,稍微优化下 if 那边

var X_Proxy = (function() {
  let instance;
  return function(...args) {
    // 就是if这里稍微优化下啦,没啥技术含量
    if (!instance) {
      instance = new X(...args);
    }
    return instance;
  };
})();

v4.0,抽象出生成单例模式的函数

任何一个类,都可以增加一个单例代理类,这样我们可以写一个函数,专门生成单例代理类。

// 其实把上个版本的X_Proxy中的X改成fn,作为参数传进去,末了去掉自执行即可
var Create_Single_Proxy = function(fn) {
  let instance;
  return function(...args) {
    if (!instance) {
      instance = new fn(...args);
    }
    return instance;
  };
};
// 任意一个普通类
function X(name) {
  this.name = name;
}
// 生成其 单例代理类
var X_Proxy = Create_Single_Proxy(X);
var a = new X_Proxy("a");
var b = new X_Proxy("b");
console.log(a === b);

v4.1,精炼下Create_Single_Proxy

var Create_Single_Proxy = function(fn) {
  let instance;
  return function(...args) {
    // 就是这里稍微优化下啦,别忘了赋值
    return instance || (instance = new fn(...args));
  };
};

以上参考《Javascript设计模式与开发实践》

目录
相关文章
|
23天前
|
存储 设计模式 测试技术
单例模式
单例模式
|
12月前
|
设计模式 安全 Java
单例模式的运用
单例模式的运用
36 0
|
设计模式 Java Spring
什么场景要使用单例模式,什么场景不能使用?
经常有小伙伴问我,设计模式学了这么久,每次看到概念也都能理解。但是,就是不知道怎么用,在哪里能用?我告诉大家,设计模式,不是为了要用而用的,而是作为前人总结下来的经验,等到哪天需要用的时候,你能想起来为你所用。
90 0
|
安全 Java
原来要这么实现单例模式
原来要这么实现单例模式
48 0
|
安全 Java
单例模式很简单
《基础系列》
108 0
单例模式很简单
|
存储 安全 调度
单例模式的简单介绍
单例模式的简单介绍
|
安全 Java
单例模式和多例模式(懒汉式和饿汉式)
单例模式和多例模式(懒汉式和饿汉式)
129 0
|
设计模式 安全 Java
回顾一下单例模式
回顾一下单例模式
|
设计模式 缓存
我学会了,单例模式
单例模式属于创建型模式,这个类型的设计模式是将 对象的创建和使用解耦了,花式的去创建对象。
120 0
我学会了,单例模式
|
设计模式 数据库 Python