1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>javascript高级语法14-组合模式实现</title> 6 </head> 7 <body> 8 <script> 9 //接口 10 var Interface = function(name,methods){ 11 if(arguments.length != 2){ 12 alert("interface must have two paramters..."); 13 } 14 this.name = name;//这个是接口的名字 15 this.methods = [];//定义个空数组来转载函数名 16 for (var i = 0; i < methods.length; i++) { 17 if(typeof methods[i] != "string"){ 18 alert("method name must is String ...") 19 }else{ 20 this.methods.push(methods[i]) 21 } 22 } 23 } 24 //定义接口的一个静态方法来实现接口与实现类的直接检验 25 //静态方法不要写成Interface.prototype.* 因为这是写到接口原型连上的 26 //我们要把静态的函数直接写到类层次上 27 Interface.ensureImplements = function(object){ 28 if(arguments.length<2){ 29 alert("必须最少是2个参数"); 30 return false; 31 } 32 //遍历 33 for (var i = 1; i < arguments.length; i++) { 34 var inter = arguments[i]; 35 //如果你是接口就必须是Interface类型的 36 if(inter.constructor != Interface){ 37 throw new Error("if is interface class must is Interface type"); 38 } 39 //遍历函数集合并分析 40 for (var j = 0; j < inter.methods.length; j++) { 41 var method = inter.methods[j]; 42 //实现类中必须有方法名字 和 接口中所有的方法名项目 43 if(!object[method] || typeof object[method] != "function"){ 44 throw new Error("实现类并没有完全实现接口中的所有方法..."); 45 } 46 } 47 } 48 } 49 50 /* 51 * 组合模式 52 */ 53 54 function demo(){ 55 var composite = new Interface("composite",["getChildByName","add"]); 56 var student = new Interface("composite",["goToClass","finishClass"]); 57 //定义组合类 58 var compositeObj = function(name){ 59 this.name = name; 60 this.type = "com"; //默认是组合类 61 var childs = new Array(); 62 //得到相关的所有孩子节点 63 this.getChildByName=function(name){ 64 //涉及到递归 65 var toChilds = new Array(); 66 if(!name){ 67 for(var i=0;i<childs.length;i++){ 68 if(childs[i].type == "com"){ //组合节点 69 toChilds = toChilds.concat(childs[i].getChildByName()); 70 }else{ //叶子节点 71 toChilds.push(childs[i]); 72 73 } 74 } 75 }else{ 76 for(var i=0;i<childs.length;i++){ 77 if(childs[i].name == name){ 78 if(childs[i].type == "com"){ 79 toChilds = toChilds.concat(childs[i].getChildByName()); 80 break; 81 }else{ 82 toChilds.push(childs[i]); 83 break; 84 } 85 }else{ 86 if(childs[i].type == "com"){ 87 toChilds = toChilds.concat(childs[i].getChildByName(name)); 88 } 89 } 90 } 91 } 92 return toChilds; 93 } 94 //增加子节点 95 this.add = function(child){ 96 childs.push(child); 97 return this; 98 } 99 //上课 100 this.goToClass = function(name){ 101 var toChilds = this.getChildByName(name); 102 for(var i=0;i<toChilds.length;i++){ 103 toChilds[i].goToClass(); //子类的GoToClass方法 104 } 105 } 106 //下课 107 this.finishClass = function(name){ 108 var toChilds = this.getChildByName(name); 109 for(var i=0;i<toChilds.length;i++){ 110 toChilds[i].finishClass(); //子类的GoToClass方法 111 } 112 } 113 //接口验证 114 Interface.ensureImplements(this,composite,student); 115 } 116 //定义叶子类 117 var studentObj = function(name){ 118 this.name = name; 119 this.type = "stu";//默认是叶子 120 121 //得到相关的所有孩子节点 122 this.getChildByName=function(name){ 123 if(this.name == name){ 124 return this; 125 }else{ 126 return null; 127 } 128 } 129 //增加子节点 130 this.add = function(child){ 131 throw new Error("add 不能被初始化在叶子类中!"); 132 } 133 //上课 134 this.goToClass = function(name){ 135 document.write(this.name + "去上课<br>") 136 } 137 //下课 138 this.finishClass = function(name){ 139 document.write(this.name + " 下课<br>") 140 } 141 Interface.ensureImplements(this,composite,student); 142 } 143 144 //测试; 145 var a = new studentObj("a"); 146 var b = new studentObj("b"); 147 var c = new studentObj("c"); 148 var d = new studentObj("d"); 149 var e = new studentObj("e"); 150 var f = new studentObj("f"); 151 var g = new studentObj("g"); 152 var h = new studentObj("h"); 153 var one = new compositeObj("一班"); 154 var oneOne = new compositeObj("一班一组"); 155 oneOne.add(a).add(b); 156 var oneTwo = new compositeObj("一班二组"); 157 oneTwo.add(c).add(d); 158 one.add(oneOne).add(oneTwo); 159 var two = new compositeObj("二班"); 160 var twoOne = new compositeObj("二班一组"); 161 twoOne.add(e).add(f); 162 var twoTwo = new compositeObj("二班二组"); 163 twoTwo.add(g).add(h); 164 two.add(twoOne).add(twoTwo); 165 var xuexiao = new compositeObj("新学校"); 166 xuexiao.add(one).add(two); 167 168 //客户端调用API 169 xuexiao.goToClass(); 170 document.write("------------------------<br>"); 171 xuexiao.goToClass("一班"); 172 document.write("------------------------<br>"); 173 xuexiao.goToClass("二班一组"); 174 document.write("------------------------<br>"); 175 xuexiao.goToClass("a"); 176 177 } 178 demo(); 179 </script> 180 </body> 181 </html>