一、组合模式定义及使用场景
组合模式将对象组合成树形结构,用以表示“部分—整体”的层次结构,除了用来表示树形结构之外,组合模式还可以利用对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性。
实现组合模式的关键:
在java等静态语言中,需要单个对象和组合对象都实现同样的抽象接口,对外提供同样的方法,(具有的属性可以不同哈),这可以通过抽象类或者接口来实现。
在javascript中,对象的多态性是与生俱来的,没有编译器去检查对象的类型,因此实现组合模式的要点是保证组合兑现个单个对象用友同样的方法,这通常需要使用“鸭子类型”的思想来对它们进行接口检查。
二、组合模式应用案例—扫描文件夹
//组合模式的学习:扫描文件夹 var Folder=function(name){ this.name=name; this.files=[]; }; Folder.prototype.add=function(file){ this.files.push(file); }; Folder.prototype.scan=function(){ console.log('开始扫描文件夹:'+this.name); for(var i=0,len=this.files.length;i<len;i++){ this.files[i].scan(); } }; var File=function(name){ this.name=name; }; File.prototype.add=function(){ throw new Error('文件下面不能添加文件!'); }; File.prototype.scan=function(){ console.log('开始扫描文件:'+this.name); }; //测试 var folder1=new Folder('技术类书籍'); var file1=new File('javascipt技术精粹'); folder1.add(file1); var folder2=new Folder('文学类书籍'); var file2=new File('近距离看美国'); folder2.add(file2); var file3=new File('宠物的秘密'); var folder=new Folder('总文件夹'); folder.add(folder1); folder.add(folder2); folder.add(file3); folder.scan();
使用基于委托的写法来实现组合模式
//使用基于委托的方式重写策略模式 var Folder={ init:function(name){ this.files=[]; this.name=name; }, add:function(file){ this.files.push(file); }, scan:function(){ var i,len,curFile; for(i=0,len=this.files.length;i<len;i++){ curFile=this.files[i]; curFile.scan(); } } }; var File={ init:function(name){ this.name=name; }, add:function(){ throw new Error('文件下面不能添加'); }, scan:function(){ console.log(this.name); } }; var file=Object.create(File); file.init('javascript'); var file2=Object.create(File); file2.init('C++'); var folder1=Object.create(Folder); folder1.init('folder1'); folder1.add(file); folder1.add(file2); var folder2=Object.create(Folder); folder2.init('folder2'); folder2.add(folder1); folder2.scan();