1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>工厂设计模式</title> 6 7 <!-- 8 @theme: javascript高级 工厂模式设计 9 @autor:EthanCoco 10 @date:2015-11-21 11 @email:[email protected] 12 --> 13 14 15 16 <script type=text/javascript charset=utf-8> 17 //创建一个命名空间 18 var LJL = {}; 19 20 /** 21 *建一个接口 22 *接口需要两个参数 23 *参数1: 接口的名字(string) 24 *参数2: 方法名称(数组(string)) 25 */ 26 LJL.Interface = function(name,methods){ 27 if(arguments.length !== 2){//判断接口参数个数是否正确 28 throw new Error("参数个数不正确!"); 29 } 30 this.name = name; 31 this.methods = [];//定义一个内置的空数组接受方法名称里的元素 32 for(var i = 0;i < methods.length;i++){ 33 if(typeof methods[i] !== ‘string‘){ 34 throw new Error("方法名称错误,必须是字符串类型!"); 35 } 36 //把传入参数的元素全部放到内置的methods中去 37 this.methods.push(methods[i]); 38 } 39 40 }; 41 42 /** 43 *接口静态方法 44 *参数:object 45 *检验接口里的方法是否实现 46 *如果通过不做任何操作,如果不通过,抛出error 47 *目的:检测方法是否全部实现 48 *object 要求参数必须有两个以上 49 *一个是对象实例 50 *其它是要检验的接口对象 51 */ 52 LJL.Interface.checkMethodsIsPass = function(object){ 53 if(arguments.length < 2){//判断参数,如果参数小于2,抛出异常 54 throw new Error("要求参数必须有两个以上@param1=实例对象,其它参数是接口对象!"); 55 } 56 //获得接口实例对象 57 for(var i = 1;i<arguments.length;i++){//i=1是因为第二个参数是需要检测的接口 58 var instanceInterface = arguments[i]; 59 //判断参数是否是接口对象 60 if(instanceInterface.constructor !== LJL.Interface){ 61 throw new Error("参数是不是接口对象!"); 62 } 63 //如果是,检测接口对象里的方法是否实现 64 for(var j = 0;j<instanceInterface.methods.length;j++){ 65 //用历史变量接受一个方法的名称,名称是字符串,如果不是就抛出error 66 var methodName = instanceInterface.methods[j]; 67 //object[key]表示的就是方法 68 //方法是一个函数,需要判断 69 if(!object[methodName] || typeof object[methodName] !== ‘function‘){ 70 throw new Error("这个方法 ‘" + methodName + "‘ 找不到!"); 71 } 72 } 73 74 } 75 76 }; 77 78 /** 79 * 继承方法 80 * @param {Object} sub 81 * @param {Object} sup 82 */ 83 LJL.extend=function(sub ,sup){ 84 // 目的: 实现只继承父类的原型对象 85 var F = new Function(); // 1 创建一个空函数 目的:空函数进行中转 86 F.prototype = sup.prototype; // 2 实现空函数的原型对象和超类的原型对象转换 87 sub.prototype = new F(); // 3 原型继承 88 sub.prototype.constructor = sub ; // 4还原子类的构造器 89 //保存一下父类的原型对象: 一方面方便解耦 另一方面方便获得父类的原型对象 90 sub.superClass = sup.prototype; //自定义一个子类的静态属性 接受父类的原型对象 91 //判断父类的原型对象的构造器 (加保险) 92 if(sup.prototype.constructor == Object.prototype.constructor){ 93 sup.prototype.constructor = sup ; //手动欢迎父类原型对象的构造器 94 } 95 }; 96 97 98 //////////////////////////////////////////////// 99 //以上都是为工厂设计模式做必要的准备 100 //////////////////////////////////////////////// 101 102 //思路整理 103 /** 104 *设计一个买电脑的工厂设计模式 105 *首先,得有一个“工厂”; 106 *其次,工厂用来“生产电脑”; 107 *然后,电脑需要“卖出去”; 108 *继续,卖出去需要一个“专卖店” 109 *最后,买电脑的人到什么样的商店去“买什么样的电脑” 110 */ 111 112 //生产电脑的工厂 目的:生产车 113 var PCFactory = { 114 //里面有生产电脑的方法 115 createPC : function(type){//type 动态生产电脑类型,即客户需要的电脑生产 116 //利用eval动态创建传入类型的实例对象 117 var pc = eval(‘new ‘+type+‘()‘); 118 //电脑在生产的时候就需要检测是否合格! 119 //第一个参数是电脑的实例对象 120 //第二个参数是接口的实例对象 121 LJL.Interface.checkMethodsIsPass(pc,PCInterface); 122 return pc; 123 } 124 }; 125 126 //创建接口实例对象 127 //接口需要有两个参数 128 //一个是接口的实例对象,一个是方法(数组),open(开机),run(运行) 129 var PCInterface = new LJL.Interface(‘PCInterface‘,[‘open‘,‘run‘]); 130 131 //创建一个电脑的基类 132 function BasePC(){} 133 //在原型对象上实现方法 134 BasePC.prototype = { 135 constructor : BasePC,//还原构造器 136 open : function(){ 137 alert(this.constructor.name + "...open"); 138 }, 139 run : function(){ 140 alert(this.constructor.name + "...run"); 141 } 142 }; 143 144 145 //电脑有不同的品牌,不同的专卖店提供不同的电脑 146 //创建一个抽象的基类专卖店 147 function PCShop(){} 148 PCShop.prototype = { 149 constructor : PCShop , 150 //买电脑的方法 151 sellPC:function(type){ 152 this.abstractSellPC(type); 153 } , 154 abstractSellPC: function(){ 155 throw new Error(‘this method is abstract...‘); 156 } 157 }; 158 159 //创建不同品牌的专门店 160 161 162 163 /////////////////////////////////////////////////// 164 //戴尔专卖店 165 function DellPCShop(){} 166 //每个店都有卖电脑的方法,所以我们继承PCShop里的方法 167 LJL.extend(DellPCShop,PCShop); 168 //电脑专卖店有不同型号的dell电脑 169 DellPCShop.prototype = { 170 constructor : DellPCShop, 171 sellPC : function(type){ 172 var pc ; 173 var pctypes = [‘dellx1‘,‘dellx5‘,‘dellx8‘];//所有dell电脑的型号 174 for(i in pctypes){ 175 //判断商店是否有你要的型号 176 if(pctypes[i] === type){ 177 pc = PCFactory.createPC(type); 178 break; 179 }else{ 180 throw new Error("没有你要的型号!"); 181 } 182 } 183 return pc; 184 } 185 }; 186 187 //dell电脑不同型号的方法检测实现 188 //检测不同品牌的电脑 189 function dellx1(){} 190 LJL.extend(dellx1,BasePC); //继承基类的方法 191 192 function dellx5(){} 193 LJL.extend(dellx5,BasePC); 194 195 function dellx8(){} 196 LJL.extend(dellx8,BasePC); 197 ////////////////////////////////////////////// 198 199 200 201 var shop = new DellPCShop(); 202 var pc = shop.sellPC(‘dellx1‘); 203 pc.open(); 204 </script> 205 </head> 206 <body> 207 </body> 208 </html>
时间: 2024-09-30 10:59:51