单例模式
概念
- 一个 对象/实例 只能被创建一次
- 创建之后缓存起来,以后继续使用
- 即,一个系统中只有一个
Typescript 静态属性
- 普通属性是 实例属性/对象属性
- static 静态属性
class Foo {
name: string;
constructor(name: string) {
this.name = name;
}
getName() {
return this.name;
}
static flag = '二次元';
static getFlag() {
return this.flag;
}
}
const f1 = new Foo('张三');
f1.name;
f1.getName();
Foo.flag;
Foo.getFlag();
export {};
UML 类图

代码演示
class Singleton {
private constructor() {
}
private static instance: Singleton | null;
static getInstance(): Singleton {
if (Singleton.instance == null) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
const s1 = Singleton.getInstance();
const s2 = Singleton.getInstance();
console.log(s1 === s2);
export {};
// src/demo04/js.js
function genGetInstance() {
let instance; // 闭包
class SingleTon {
// ...
}
return () => {
if (instance == null) {
instance = new SingleTon();
}
return instance;
};
}
const getInstance = genGetInstance();
const s1 = getInstance();
const s2 = getInstance();
console.log(s1 === s2); // true
let instance;
class SingleTon {}
export default () => {
if (instance == null) {
instance = new SingleTon();
}
return instance;
};
场景
JQuery 只有一个 $
if (window.JQuery != null) {
return window.JQuery;
} else {
}
模拟登录框
class LoginForm {
constructor() {
this.state = 'hide';
}
show() {
if (this.state === 'show') {
console.log('已经显示');
} else {
this.state = 'show';
console.log('登录框显示成功');
}
}
hide() {
if (this.state === 'hide') {
console.log('已经隐藏');
} else {
this.state = 'hide';
console.log('登录框隐藏成功');
}
}
}
LoginForm.getInstance = (function () {
let instance;
return function () {
if (!instance) {
instance = new LoginForm();
}
return instance;
};
})();
let login1 = LoginForm.getInstance();
login1.show();
let login2 = LoginForm.getInstance();
login2.hide();
console.log('login1 === login2:', login1 === login2);
其他
设计原则验证
- 内部封装 getInstance,高内聚、低耦合
- 符合单一职责原则,只能实例化唯一的对象
- 没法具体开放封闭原则,但是绝对不违反开放封闭原则
注意
- JS 是单线程语言,如果是 Java 等多线程语言,单例模式需要加线程锁。
- 静态方法中的 this
- 前端用到严格的单例模式并不多,但单例模式的思想到处都有