-
问题场景
操作层层嵌套的数据结构 -
解决思路
提供叶对象和组合对象构成的树形结构,组合对象调用叶对象的同名接口,客户只需知道顶层对象即可用同一个接口遍历整个结构,且添加新对象后不用修改现有代码。 -
具体实现
var Folder = function (name) {
this.name = name;
this.files = [];
this.parent = null;
};
Folder.prototype.add = function (file) {
file.parent = this; //把this作为file的父节点
this.files.push(file);
};
Folder.prototype.scan = function () {
console.log("开始扫描文件夹:", this.name);
for (var i = 0, file, files = this.files; file = files[i++];) {
file.scan();
}
};
Folder.prototype.remove = function () {
if (!this.parent) {
console.log(123);
return;
}
for (var files = this.parent.files, l = files.length - 1; l >= 0; l--) {
if (files[l] === this) {
files.splice(l, 1);
}
}
}
//叶对象
var File = function (name) {
this.name = name;
this.parent = null;
};
File.prototype.add = function () {
throw new Error("文件下不能添加文件");
};
File.prototype.scan = function () {
console.log("开始扫描文件:", this.name);
};
File.prototype.remove = function () {
if (!this.parent) {
return;
}
for (var files = this.parent.files, l = files.length; l >= 0; l--) {
var file = files[l];
if (file === this) {
files.splice(l, 1);
}
}
}
var Folder1 = new Folder("Folder1");
var Folder2 = new Folder("Folder2")
var file1 = new File("file1");
Folder1.add(Folder2);
Folder1.add(file1);
var Folder3 = new Folder("Folder3");
var file2 = new File("file2");
Folder2.add(Folder3);
Folder2.add(file2);
var file3 = new File("file3");
Folder3.add(file3);
Folder1.scan();//操作顶层对象即可
// 开始扫描文件夹: Foler1
// VM36: 9 开始扫描文件夹: Folder2
// VM36: 9 开始扫描文件夹: Folder3
// VM36: 22 开始扫描文件: file3
// VM36: 22 开始扫描文件: file2
// VM36: 22 开始扫描文件: file1
Folder2.remove();
Folder1.scan();
// 删除后
// 开始扫描文件夹: Folder1
// 开始扫描文件夹: Folder2
// 开始扫描文件: file2
// 开始扫描文件: file1
- 优缺点
优点: 在开发期间不知道树存在多少层次的时候,用此结构可方便添加和删除,以及访问;客户统一对待组合节点和叶节点,用一个接口即可实现遍历(递归)
缺点:组合对象和叶对象非常像,只有在运行时候区别才会显现??
创建了大量对象,可能使系统负担不起。