JavaScript享元模式

享元模式:

剥离出对象的外部状态和内部状态,将内部状态放在类中,外部状态可以通过同一个对象共享,即用相对较少的共享对象取代大量对象,常用在创建很多类似的对象而导致内存过高的场景中。

最常见的场景就是上传文件,上传的文件有文件名,文件大小,上传文件的方式,分为普通上传和极速上传。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class UploadFile {
constructor(type, id, name, size) {
this.type = type;
this.id = id;
this.name = name;
this.size = size;
}
delete() {
console.log('delete file');
}
}

var startUpload = function(type, files) {
for(var i = 0; i < files.length; i++ ) {
new UploadFile(type, i, file[i].name, file[i].size);
}
}

如上实现代码,如果用户同时上传了几千个文件,那么同时也创建了几千个对象,就会导致内存占用过高。

使用享元模式来改进代码,将对象的内部状态剥离出来,即不变的状态,即文件的上传方式,而对象的外部状态如文件名,文件大小是外部状态,实现如下:

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
30
31
32
class UploadFile {
constructor(type) {
this.type = type;
}
delete() {
console.log('delete file');
}
}

var uploadFactory = (function() {
var cache = {};
return function(type) {
if(cache[type]) {
return cache[type];
}
return cache[type] = new UploadFile(type);
}
})();

var uploadManager = function(type, id, name, size) {
var obj = uploadFactory(type);
obj['id'] = id;
obj['name'] = name;
obj['size'] = size;
};

var startUpload = function(type, files) {
for(var i = 0; i < files.length; i++ ) {
uploadManager(type, i, file[i].name, file[i].size);
}
}

如此这样一来,创建的实例对象就只有2个,而文件的其他外部属性则通过id区别保存在同一个实例对象上。通过享元模式则得到了实例对象的大幅度释放。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!