享元模式:
剥离出对象的外部状态和内部状态,将内部状态放在类中,外部状态可以通过同一个对象共享,即用相对较少的共享对象取代大量对象,常用在创建很多类似的对象而导致内存过高的场景中。
最常见的场景就是上传文件,上传的文件有文件名,文件大小,上传文件的方式,分为普通上传和极速上传。如下:
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区别保存在同一个实例对象上。通过享元模式则得到了实例对象的大幅度释放。