这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战
单例模式
下面我们学习单例模式,单例模式也是很常用的。它能保证这个类的实例只有一个。
通常在弹窗这种地方会用到单例模式,只允许全局只有唯一一个弹窗。
在这个例子里面,我们想要实现的效果是,当类实例化两次的时候,能够返回同样的实例,也就是下面的代码,打印出 true。
我们先来看看 dialog 弹窗是如何实现的。
首先我们定义了一个私有的静态属性:instance,用来存储这个全局唯一的实例,所以它的类型就是 Dialog。
接着我们定义了一个静态方法:getInstance,用来返回全局唯一的实例,如果它没有被创建的话,就直接 new 一个,如果已经创建的,就直接返回实例即可。
接下来,我们定义了 constructor 构造函数方法,需要注意的是,我们将它定义为 private
私有方法,这样就可以避免直接在外面通过 new 来创建实例,在只允许在这个类的内部通过 new 来创建实例。
class Dialog {
private static instance: Dialog = null;
static getInstance() {
if (!Dialog.instance) {
Dialog.instance = new Dialog();
}
return Dialog.instance;
}
/*
单例模式,仅允许通过 Dialog.getInstance 获取全局唯一实例
*/
private constructor() {
}
}
const a = new Dialog();
const b = new Dialog();
console.log(a === b); // 希望这里是 true
复制代码
我们来看下这个报错信息。
这里的构造函数,是私有方法,所以不可以通过 new 的方式去创建这个实例。
修改下代码
class Dialog {
private static instance: Dialog = null;
static getInstance() {
if (!Dialog.instance) {
Dialog.instance = new Dialog();
}
return Dialog.instance;
}
/*
单例模式,仅允许通过 Dialog.getInstance 获取全局唯一实例
*/
private constructor() {
}
}
const a = Dialog.getInstance();
const b = Dialog.getInstance();
console.log(a === b); // true
复制代码
这样的话,通过这种单例模式,实现这种全局唯一实例的目的。
习题:理解单例模式,并计算生产编号
class Animal {
private name: string;
private static id = 0;
// 工厂模式车间
constructor(name: string) {
this.name = name;
Animal.id++;
}
getAnimalInfo() {
return `我是火星工厂生产的${this.name},生产编号为${Animal.id}`;
}
// 单例模式车间(我们车间一生只生成一次,保证全宇宙唯一)
private static instance: Animal;
static onlyOne(name: string) {
if (!Animal.instance) {
Animal.instance = new Animal(name);
}
return Animal.instance;
}
}
Animal.onlyOne('panda').getAnimalInfo(); // 生产编号为 ?
Animal.onlyOne('panda').getAnimalInfo(); // 生产编号为 ?
复制代码
答案:
1 1
解析:
单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。
题目使用了单例模式。大家可以仔细看看哦。本题目依然是输出生产编号,生产编号依旧定义为类的静态属性,我们使用了单例模式实现了,类的实例总是唯一存在。因此两次的生产编号均为 1
。