场景:定义一个抽象类 AbsProducer(生产商),该生产商有两个行为,一个生产,一个出售,其中生产方法为抽象方法,由具体的厂家(工厂)去实现,出售的产品均是电子产品(返回的对象为电子产品对象,即对象都要实现电子产品的接口)。其中有联想和apple两个工厂,根据传入的参数生产旗下不同的电子产品。具体代码实现如下:
1 1 /*定义一个抽象类 AbsProducer(生产商),该生产商有两个行为,一个生产,一个出售,其中生产方法为抽象方法,由具体的厂家去实现*/ 2 2 var AbsProducer = function(){}; 3 3 AbsProducer.prototype = { 4 4 5 5 sell:function(name){ 6 6 var product = this.create(model); 7 7 product.showName(); 8 8 return product; 9 9 }, 10 10 create:function(name){ 11 11 throw new Error("抽象类不支持该操作"); 12 12 } 13 13 }
联想工厂:LenovoFactory.js
1 var LenovoFactory = function(){}; 2 extend(LenovoFactory,AbsProducer); 3 LenovoFactory.prototype.create = function(name){ 4 var product; 5 switch(name){ 6 case "phone": 7 product = new LenovoPhone(); 8 break; 9 case "computer": 10 product = new LenovoComputer(); 11 break; 12 default: 13 product = new LenovoPad(); 14 } 15 Interface.ensureImplements(product,ElectronicProduct); 16 product.showName(); 17 return product; 18 } 19 20 /*Lenovo phone class*/ 21 function LenovoPhone(){}; 22 LenovoPhone.prototype = { 23 showName:function(){ 24 console.log("我是联想厂商生产的手机,取名为Lenovo-phone"); 25 }, 26 showCpu:function(){ 27 console.log("联想手机cpu一般般咯"); 28 }, 29 showSysType:function(){ 30 console.log("姑且认为联想手机系统为WP吧"); 31 } 32 }; 33 34 function LenovoComputer(){}; 35 LenovoComputer.prototype = { 36 showName:function(){ 37 console.log("我是联想厂商生产的电脑,型号为Y系列"); 38 }, 39 showCpu:function(){ 40 console.log("联想电脑cpu,四代I7处理器"); 41 }, 42 showSysType:function(){ 43 console.log("联想电脑系统为正版win7"); 44 } 45 }; 46 47 function LenovoPad(){}; 48 LenovoPad.prototype = { 49 showName:function(){ 50 console.log("我是联想厂商生产的平板"); 51 }, 52 showCpu:function(){ 53 console.log("联想平板,cpu是多少,不是很清楚额..."); 54 }, 55 showSysType:function(){ 56 console.log("联想平板系统为win8家庭版"); 57 } 58 };
苹果工厂:AppleFactory.js
1 var AppleFactory = function(){}; 2 extend(AppleFactory,AbsProducer); 3 AppleFactory.prototype.create = function(name){ 4 var product; 5 switch(name){ 6 case "phone": 7 product = new Iphone(); 8 break; 9 case "computer": 10 product = new Mac(); 11 break; 12 default: 13 product = new IPad(); 14 } 15 Interface.ensureImplements(product,ElectronicProduct); 16 product.showName(); 17 return product; 18 }; 19 20 function Iphone(){}; 21 Iphone.prototype = { 22 showName:function(){ 23 console.log("我是苹果公司生产的手机,取名为Iphone"); 24 }, 25 showCpu:function(){ 26 console.log("iphone手机CPU是基于ARM架构重新设计的"); 27 }, 28 showSysType:function(){ 29 console.log("iphone系统为IOS9"); 30 } 31 }; 32 function Mac(){}; 33 Mac.prototype = { 34 showName:function(){ 35 console.log("我是苹果公司生产的电脑,取名为Mac"); 36 }, 37 showCpu:function(){ 38 console.log("mac cpu还不错吧"); 39 }, 40 showSysType:function(){ 41 console.log("mac系统为OS X"); 42 } 43 }; 44 function IPad(){}; 45 IPad.prototype = { 46 showName:function(){ 47 console.log("我是苹果公司生产的ipad,取名为ipad"); 48 }, 49 showCpu:function(){ 50 console.log("ipad cpu很厉害咯"); 51 }, 52 showSysType:function(){ 53 console.log("ipad 系统为IOS系统"); 54 } 55 }
调用:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>工厂模式</title> 6 </head> 7 <body> 8 </body> 9 </html> 10 <script type="text/javascript" src="Interface.js" ></script> 11 <script type="text/javascript" src="AbsProducer.js" ></script> 12 <script type="text/javascript" src="LenovoFactory.js" ></script> 13 <script type="text/javascript" src="AppleFactory.js" ></script> 14 <script type="text/javascript"> 15 /*定义了一个ElectronicProduct电子产品的接口,该接口有以下几个名称*/ 16 var ElectronicProduct = new Interface("ElectronicProduct",["showName","showCpu","showSysType"]); 17 //这里你想要哪个品牌的电子产品,直接new一个该品牌的工厂即可。 18 var factory = new AppleFactory(); 19 var product = factory.create("phone"); 20 product.showSysType(); 21 product.showCpu(); 22 </script>
公共类:Interface.js
1 // Constructor. 2 var Interface = function(name, methods) { 3 if(arguments.length != 2) { 4 throw new Error("Interface constructor called with " + arguments.length 5 + "arguments, but expected exactly 2."); 6 } 7 8 this.name = name; 9 this.methods = []; 10 for(var i = 0, len = methods.length; i < len; i++) { 11 if(typeof methods[i] !== 'string') { 12 throw new Error("Interface constructor expects method names to be " 13 + "passed in as a string."); 14 } 15 this.methods.push(methods[i]); 16 } 17 }; 18 19 // Static class method. 20 21 Interface.ensureImplements = function(object) { 22 if(arguments.length < 2) { 23 throw new Error("Function Interface.ensureImplements called with " + 24 arguments.length + "arguments, but expected at least 2."); 25 } 26 27 for(var i = 1, len = arguments.length; i < len; i++) { 28 var interface = arguments[i]; 29 if(interface.constructor !== Interface) { 30 throw new Error("Function Interface.ensureImplements expects arguments " 31 + "two and above to be instances of Interface."); 32 } 33 34 for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) { 35 var method = interface.methods[j]; 36 if(!object[method] || typeof object[method] !== 'function') { 37 throw new Error("Function Interface.ensureImplements: object " 38 + "does not implement the " + interface.name 39 + " interface. Method " + method + " was not found."); 40 } 41 } 42 } 43 }; 44 45 function extend(subClass,superClass){ 46 var F = function(){}; 47 F.prototype = superClass.prototype; 48 subClass.prototype = new F(); 49 subClass.prototype.constructor = subClass; 50 51 subClass.superClass = superClass.prototype; 52 if(superClass.prototype.constructor == Object.prototype.constructor){ 53 superClass.prototype.constructor = superClass; 54 } 55 }