JavaScript设计模式-16.装饰者模式(上)

  1 <!DOCTYPE html>
  2 <html>
  3     <head>
  4         <meta charset="UTF-8">
  5         <title>javascript 高级语法16-装饰者模式</title>
  6     </head>
  7     <body>
  8         <script>
  9             /*通过需求引出装饰者模式
 10              * 
 11              */
 12             
 13             //接口
 14             var Interface = function(name,methods){
 15                 if(arguments.length != 2){
 16                     alert("interface must have two paramters...");
 17                 }
 18                 this.name = name;//这个是接口的名字
 19                 this.methods = [];//定义个空数组来转载函数名
 20                 for (var i = 0; i < methods.length; i++) {
 21                     if(typeof methods[i] != "string"){
 22                         alert("method name must is String ...")
 23                     }else{
 24                         this.methods.push(methods[i])
 25                     }
 26                 }
 27             }
 28             //定义接口的一个静态方法来实现接口与实现类的直接检验
 29             //静态方法不要写成Interface.prototype.* 因为这是写到接口原型连上的
 30             //我们要把静态的函数直接写到类层次上
 31             Interface.ensureImplements = function(object){
 32                 if(arguments.length<2){
 33                     alert("必须最少是2个参数");
 34                     return false;
 35                 }
 36                 //遍历
 37                 for (var i = 1; i < arguments.length; i++) {
 38                     var inter = arguments[i];
 39                     //如果你是接口就必须是Interface类型的
 40                     if(inter.constructor != Interface){
 41                         throw new Error("if is interface class must is Interface type");
 42                     }
 43                     //遍历函数集合并分析
 44                     for (var j = 0; j < inter.methods.length; j++) {
 45                         var method = inter.methods[j];
 46                         //实现类中必须有方法名字 和 接口中所有的方法名项目
 47                         if(!object[method] || typeof object[method] != "function"){
 48                             throw new Error("实现类并没有完全实现接口中的所有方法...");
 49                         }
 50                     }
 51                 }
 52             }
 53             
 54             function demo(){
 55                 //汽车店的接口
 56                 var CarShop = new Interface("CarShop",["getPrice","assemble"]);
 57                 var myCarShop = function(){
 58                     this.getPrice = function(){
 59                         document.write(15000+"<br>");
 60                     }
 61                     this.assemble = function(){
 62                         document.write("汽车组装..."+"<br>")
 63                     }
 64                     Interface.ensureImplements(this,CarShop);
 65                 }
 66                 
 67                 var jimCarShop = new myCarShop();
 68                 jimCarShop.getPrice();
 69                 jimCarShop.assemble();            
 70                 document.write("--------------------"+"<br>")
 71                 
 72                 /*新需求:
 73                  * 汽车还会有附属产品  音响 (k),真皮沙发(M),保险杠(N)
 74                  * 每一个附属的产品会影响到汽车的组装和其价格
 75                  * 你能想到什么办法?
 76                  */
 77                 
 78                 //改写接口
 79                 var CarShop2 = new Interface("CarShop2",["getPrice","assemble","addK","addM","addN"]);
 80                 var myCarShop2 = function(){
 81                     var price = 150000;
 82                     this.getPrice = function(){
 83                         document.write(price+"<br>")
 84                     }
 85                     this.assemble = function(){
 86                         document.write("汽车组装"+"<br>")
 87                     }
 88                     this.addK = function(){
 89                         price += 1000;
 90                     }
 91                     this.addM = function(){
 92                         price += 2000;
 93                     }
 94                     this.addN = function(){
 95                         price += 3000;
 96                     }
 97                     Interface.ensureImplements(this,CarShop2);
 98                 }
 99                 
100                 var jimCarShop2 = new myCarShop2();
101                 jimCarShop2.addK();
102                 jimCarShop2.addM();
103                 jimCarShop2.addN();
104                 jimCarShop2.getPrice();
105                 jimCarShop2.assemble();
106                 
107                 /*好像能成功,但是新的问题来了
108                  * 你把接口全改了,可是我继承本接口的类不一定全要有音响,沙发,保险杠。
109                  * 难道我要改变所有实现本接口的实现类吗?
110                  * 显然是不对的。
111                  */
112                 //2.如果不改变接口,那我就增加子类
113                 var CarShop = new Interface("CarShop",["getPrice","assemble"]);
114                 var myCarShop = function(){
115                     this.getPrice = function(){
116                         document.write(150000+"<br>");
117                     }
118                     this.assemble = function(){
119                         document.write("汽车组装..."+"<br>")
120                     }
121                     Interface.ensureImplements(this,CarShop);
122                 }
123                 var myCarShopM = function(){
124                     this.getPrice = function(){
125                         document.write(150100+"<br>");
126                     }
127                     this.assemble = function(){
128                         document.write("汽车组装..."+"<br>")
129                     }
130                     Interface.ensureImplements(this,CarShop);
131                 }
132                 var myCarShopK = function(){
133                     this.getPrice = function(){
134                         document.write(150200+"<br>");
135                     }
136                     this.assemble = function(){
137                         document.write("汽车组装..."+"<br>")
138                     }
139                     Interface.ensureImplements(this,CarShop);
140                 }
141                 //这种方式走不通
142                 /*装饰者的概念和用法:
143                  * 装饰者可以为对象添加新的特性
144                  * 透明的把对象包装在具有相同接口的新对象中
145                  */
146                 
147             }
148 //            demo();
149             function decorator(){
150                 //装饰者模式来解决需求
151                 var CarShop = new Interface("CarShop",["getPrice","assemble"]);
152                 //目标对象
153                 var myCarShop = function(){
154                     this.getPrice = function(){
155                         return 150000;
156                     }
157                     this.assemble = function(){
158                         document.write("汽车组装...<br>");
159                     }
160                     Interface.ensureImplements(this,CarShop);
161                 }
162                 //装饰类
163                 var M = function(carshop){
164                     this.getPrice = function(){
165                         return 1000 + carshop.getPrice();
166                     }
167                     this.assemble = function(){
168                         document.write("M组装...<br>");
169                     }
170                     Interface.ensureImplements(this,CarShop);
171                 }
172                 var K = function(carshop){
173                     this.getPrice = function(){
174                         return 2000 + carshop.getPrice();
175                     }
176                     this.assemble = function(){
177                         document.write("k组装...<br>");
178                     }
179                     Interface.ensureImplements(this,CarShop);
180                 }
181                 var N = function(carshop){
182                     this.getPrice = function(){
183                         return 3000 + carshop.getPrice();
184                     }
185                     this.assemble = function(){
186                         document.write("N组装...<br>");
187                     }
188                     Interface.ensureImplements(this,CarShop);
189                 }
190                 
191                 //调用
192                 
193                 var car =new K(new M(new myCarShop()));
194                 alert(car.getPrice());
195                 car.assemble();
196             }
197             decorator();
198         </script>
199     </body>
200 </html>
原文地址:https://www.cnblogs.com/chengyunshen/p/7191811.html