前言
提示:以下是本篇文章正文内容,下面案例可供参考
单例模式的含义
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。 保证一个类仅有一个实例,并提供一个访问它的全局访问点。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
生活中的单例模式
例如:
- 1、一个班级只有一个班主任。
- 2、一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
- 3、 一个人只有一个老婆。。。。。。
应用场景
- 1、要求生产唯一序列号。
- 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
- 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
前端中的应用场景
-
- 登录框的显示隐藏,不同组件页面,用到同一个类的实例
-
- 购物车的功能,
-
- jQuery 里面的 $只有一个
-
- vuex 和redux状态管理的 store
实现一个单例类
实现步骤
- 1、 创建一个 Singleton类
- 2、 获取实例的静态方法getInstance()
- 3、 判断是否有实例,有就返回,没有创建一个实例
- 4、 在立即调用函数IIFE里面返回,所以只生成一次, 用TypeScript写的话就时private private static SingleObject instance = new SingleObject(); //让构造函数为 private,这样该类就不会被实例化 private SingleObject(){} //获取唯一可用的对象
class Singleton {
login() {
console.log('登录一下');
}
// 使用static 说明的方法 直接用类名调用, 就不用new一个实例对象来调用
// static getInstance = (function(){
// let instance;
// return function () {
// if(instance == null) {
// instance = new Singleton();
// }
// return instance;
// }
// })()
}
Singleton.getInstance = (function(){
let instance;
return function () {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
})()
let obj1 = Singleton.getInstance()
obj1.login()
let obj2 = Singleton.getInstance()
obj2.login()
console.log('obj1 是否全等于obj2', obj1 === obj2);
console.log('----------看看通过new 实例对象的方法 出来的对象是不是等-------');
let obj3 = new Singleton()
let obj4 = new Singleton()
console.log('obj3 是否全等于obj4', obj3 === obj4);
输出情况
登录一下
登录一下
obj1 是否全等于obj2 true
----------看看通过new 实例对象的方法 出来的对象是不是等-------
obj3 是否全等于obj4 false
单例模式模拟登录框场景
class LoginForm {
constructor() {
this.state = 'hide'
}
static getInstance = (function(){
let instance;
return function() {
if (!instance) {
instance = new LoginForm()
}
return instance
}
})()
show() {
if (this.state === 'show') {
console.log('显示!!!');
return
}
this.state = 'show'
console.log('登录框已经显示');
}
hide() {
if (this.state === 'hide') {
console.log('隐藏!!!');
return
}
this.state = 'hide'
console.log('登录框已经隐藏');
}
}
let login_1 = LoginForm.getInstance()
let login_2 = LoginForm.getInstance()
login_1.show()
login_2.hide()
console.log('login_1===login_2', login_1===login_2);
输出情况
登录框已经显示
登录框已经隐藏
login_1===login_2 true
用Java实现的单例模式种类比较多,JavaScript由于是动态类型的语言就比较限制。
看看Java中的单例模式的加强版
如:懒汉式,线程安全
是否 Lazy 初始化: 是
是否多线程安全: 是
实现难度: 易
描述: 这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。\
代码
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}