JavaScript设计模式-14.组合模式实现

  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>

 

posted @ 2017-07-16 21:07  橙云生  阅读(178)  评论(0编辑  收藏  举报