享元模式
2022/4/9 大约 2 分钟
目的是减少对象/代码数量,运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
享元模式的主要优点是:
- 相同对象只要保存一份,降低了系统中对象的数量。
- 降低了系统中细粒度对象给内存带来的压力。
享元模式的主要缺点是:
- 为了使对象可以共享,需要将一些不能共享的状态外部化,这将增加程序的复杂性。
- 读取享元模式的外部状态会使得运行时间稍微变长。
# 示例一
有一百种不同文字的弹窗,每种弹窗行为相同,但是文字和样式不同,我们没必要新建一百个弹窗对象
function Pop() {};
// 保留同样的行为
Pop.prototype.action = function () {};
// 显示弹窗
Pop.prototype.show = function () {};
// 提取出每个弹窗会不同的部分作为一个外部数组
var popArr = [
{text: 'this is window1', style: [400, 400]},
{text: 'this is window2', style: [300, 300]},
]
var poper = new Pop();
for (var i = 0; i < 100; i++) {
poper.show(popArr[i]);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1、只需要一个类,不需要new一百次弹窗。 2、这个类只保留所有弹窗共有的,每个弹窗不同的部分留作为一个公共享元。
# 示例二
项目中有一个文件上传功能,该功能可以上传多个文件。
优化前
function uploader(fileType, file) {
this.fileTye = fileType;
this.file = file;
}
uploader.prototype.init = function (){/*初始化文件上传的html*/}
uploader.prototype.delete = function (){/*删除掉html*/}
uploader.prototype.uploading = function (){/*上传*/}
var file1, file2, file3
new uploader('img', file1);
new uploader('txt', file2);
new uploader('word', file3);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
未优化之前,我们上传多个不同类型的文件时,就需要new多个
uploader
的实例对象。
优化后
function uploader(fileType, file) {
this.fileTye = fileType;
this.file = file;
}
uploader.prototype.init = function (){/*初始化文件上传的html*/}
uploader.prototype.delete = function (){/*删除掉html*/}
uploader.prototype.uploading = function (){/*上传*/}
var file1, file2, file3
var data = [
{
type: 'img',
file: file1,
},
{
type: 'word',
file: file2
}
]
var uploader = new uploader('img', file1);
for (var i = 0; i < data.length; i++) {
uploader.uploading( data[i].type, data[i].file );
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
优化后我们把公共的方法(init、delete、uploading)作为享元,然后只需要循环我们的文件列表就行了
# 示例三
jquery中的extends方法,可以判断参数数量进行不同的操作。
优化前
function extend () {
if (arguments.length === 1) {
for (var item in arguments[0]) {
this[item] = arguments[0][item]
}
} else {
for (var item in arguments[1]) {
arguments[0][item] = arguments[1][item]
}
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
优化后
function extend () {
var target = arguments[0];
var source;
if (arguments.length === 1) {
target = this;
source = arguments[0];
} else {
target = arguments[0];
source = arguments[1];
}
for (var item in source) {
target[item] = source[item]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16