设计模式-javascript实现【组合模式】
定义:组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构。除了用来表示树形结构之外,组合
模式的另一个好处是通过对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性。
1. 实现组合模式
class Folder {
constructor(name, parent){
this.name = name;
this.parent = parent || null;
this.files = [];
}
add(file){
this.files.push(file);
}
scan(){
console.log('began scan folder:' + this.name);
this.files.forEach( file => file.scan());
}
remove(){
if(!this.parent) return;
const files = this.parent.files;
for (let [i, value] of files.entries()){
if(value === this){
files.splice(i, 1);
}
}
}
}
class File {
constructor(name, parent){
this.name = name;
this.parent = parent || null;
}
add() {
throw new Error('file can not add file');
}
scan(){
console.log('began scan file:' + this.name);
}
remove(){
if(!this.parent) return;
const files = this.parent.files;
for (let [i, value] of files.entries()){
if(value === this){
files.splice(i, 1);
}
}
}
}
const folder = new Folder('learn resource');
const folder1 = new Folder('javascript', folder);
const folder2 = new Folder('jQuery', folder);
const file1 = new File('javascript design pattern', folder1);
const file2 = new File('master jQuery', folder2);
const file3 = new File('refactor and pattern', folder);
folder1.add(file1);
folder2.add(file2);
folder.add(folder1);
folder.add(folder2);
folder.add(file3);
folder1.remove();
folder.scan();
注意:
- 组合模式不是父子关系
- 对叶对象操作具有一致性
- 用职责链模式提高组合模式性能
- 在某些复杂情况下,需要在父子建立双向映射关系
使用组合模式的场景:
-
表示对象的部分-整体层次结构。组合模式可以方便地构造一棵树来表示对象的部分-整体结构。特别是我们
在开发期间不确定这棵树到底存在多少层次的时候。在树的构造最终完成之后,只需要通过请求树的最顶层对
像,便能对整颗树做统一的操作。在组合模式中增加和删除树的节点非常方便,并且符合开放-封闭原则。 -
客户希望统一对待树中的所有对象。组合模式使客户可以忽略组合对象和叶对象的区别客户在面对这棵树的
时候,不用关心当前正在处理的对象是组合对象还是叶对象,也就不用写一堆if else来分别处理它们。组合
对象和叶对象会各自做自己正确的事情。