javascript设计模式-抽象工厂模式
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>抽线工厂</title> 6 </head> 7 <body> 8 9 <script> 10 /** 11 * 抽象工厂模式 12 * 13 * 定义: 提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们具体的类。 14 * 15 * 本质: 16 * 选择产品簇的实现。 17 * 18 * 功能: 19 * 为一系列相关对象或相互依赖的对象创建一个接口。这个接口内的方法不是任意堆砌的,而是一系列相关或相互依赖的方法。 20 * 从某种意义上看,抽象工厂其实是一个产品系列,或者是产品簇。 21 * 22 * 使用工厂方法来实现抽象工厂。 23 * 24 * 工厂方法是选择单个产品的实现,虽然一个类里面可以有多个工厂方法,但是这些方法之间一般是没有联系的,即使看起来像有联系。 25 * 但是抽象工厂着重的就是为一个产品簇选择实现,定义在抽象工厂里面的方法通常是由联系的,它们都是产品的某一部分或者是相互依赖的。如果抽象工厂里面只定义一个方法,直接创建产品,那么就退化成为工厂方法。 26 * 27 * 何时使用? 28 * 1.如果希望一个系统独立于它的产品的创建,组合和表示的时候。也就是一个系统只是知道产品的接口,而不关心实现的时候、 29 * 2.如果一个系统要由多个产品系列中的一个来配置的时候。也就是可以动态地切换产品簇的时候。 30 * 3.如果要强调一系列相关产品的接口,以便联合使用它们的时候。 31 * 32 * 优点: 33 * 分离接口和实现 34 * 使得切换产品簇变得容易 35 * 36 * 缺点: 37 * 不太容易扩展新产品 38 * 容易造成雷层次复杂 39 * 40 * 抽象工厂模式和单例模式 41 * 这两个模式可以组合使用。 42 * 在抽象工厂模式里面,具体的工厂实现,在整个应用中,通常一个产品系列只需要一个实例就可以了,因此可以把具体的工厂实现成为单例。 43 * 44 */ 45 // 示例代码: 46 /** 47 * 抽象工厂的接口,声明创建抽象产品对象的操作 48 */ 49 var AbstractFactory = function () {}; 50 AbstractFactory.prototype = { 51 /** 52 * 示例方法,创建抽象产品A的对象 53 * @return {[type]} 抽象产品A的对象 54 */ 55 createProductA: function () {}, 56 // 创建抽象产品B 57 createProductB: function () {} 58 }; 59 60 /** 61 * 抽象产品A,B的接口 62 */ 63 var AbstractProductA = function () {}; 64 // ... 65 var AbstractProductB = function () {}; 66 // ... 67 68 // 产品A的实现 69 var ProductA1 = function () {}; 70 ProductA1.prototype = Object.create(AbstractProductA.prototype); 71 // ... 72 73 var ProductA2 = function () {}; 74 ProductA2.prototype = Object.create(AbstractProductA.prototype); 75 // ... 76 77 // 产品B的实现 78 var ProductB1 = function () {}; 79 ProductB1.prototype = Object.create(AbstractProductB.prototype); 80 // ... 81 82 var ProductB2 = function () {}; 83 ProductB2.prototype = Object.create(AbstractProductB.prototype); 84 // ... 85 86 /** 87 * 具体的工厂实现对象,实现创建具体的产品对象的操作 88 */ 89 var ConcretFactory1 = function () {}; 90 ConcretFactory1.prototype = Object.create(AbstractFactory.prototype); 91 ConcretFactory1.prototype.createProductA = function () { 92 return new ProductA1(); 93 }; 94 ConcretFactory1.prototype.createProductB = function () { 95 return new ProductB1(); 96 }; 97 98 var ConcretFactory2 = function () {}; 99 ConcretFactory2.prototype = Object.create(AbstractFactory.prototype); 100 ConcretFactory2.prototype.createProductA = function () { 101 return new ProductA2(); 102 }; 103 ConcretFactory2.prototype.createProductB = function () { 104 return new ProductB2(); 105 }; 106 107 // 客户端 108 var af = new ConcretFactory1(); 109 af.createProductA(); 110 af.createProductB(); 111 112 113 // 示例2 114 var AMDCPU = function (id) { 115 this.id = id; 116 }; 117 var MSIMainboard = function (id) { 118 this.id = id; 119 }; 120 121 var Schema1 = function () {}; 122 Schema1.prototype = { 123 createCPUApi: function () { 124 return new AMDCPU(939); 125 }, 126 createMainboardApi: function () { 127 return new MSIMainboard(939); 128 } 129 }; 130 131 var Schema2 = function () {}; 132 Schema2 = { 133 createCPUApi: function () { 134 return new AMDCPU(1000); 135 }, 136 createMainboardApi: function () { 137 return new MSIMainboard(1000); 138 } 139 }; 140 141 var ComputerEngineer = (function () { 142 var cpu; 143 var mainboard; 144 145 function prepareHardWare(schema) { 146 cpu = schema.createCPUApi(); 147 mainboard = schema.createMainboardApi(); 148 console.log('prepared'); 149 } 150 151 var ComputerEngineer = function () { 152 cpu = null; 153 mainboard = null; 154 }; 155 ComputerEngineer.prototype = { 156 makeComputer: function (schema) { 157 prepareHardWare(schema); 158 } 159 }; 160 161 return ComputerEngineer; 162 }()); 163 164 var engineer = new ComputerEngineer(); 165 var schema = new Schema1(); 166 engineer.makeComputer(schema); 167 engineer = schema = null; 168 169 170 // http://www.dofactory.com/javascript-abstract-factory-pattern.aspx 171 172 function Employee(name) { 173 this.name = name; 174 this.say = function () { 175 log.add("I am employee " + name); 176 }; 177 } 178 179 function EmployeeFactory() { 180 this.create = function (name) { 181 return new Employee(name); 182 }; 183 } 184 185 function Vendor(name) { 186 this.name = name; 187 this.say = function () { 188 log.add("I am vendor " + name); 189 }; 190 } 191 192 function VendorFactory() { 193 this.create = function (name) { 194 return new Vendor(name); 195 }; 196 } 197 198 // log helper 199 var log = (function () { 200 var log = ""; 201 return { 202 add: function (msg) { log += msg + "\n"; }, 203 show: function () { 204 alert(log); 205 log = ""; 206 } 207 } 208 })(); 209 210 211 function run() { 212 213 var persons = []; 214 215 var employeeFactory = new EmployeeFactory(); 216 var vendorFactory = new VendorFactory(); 217 218 persons.push(employeeFactory.create("Joan DiSilva")); 219 persons.push(employeeFactory.create("Tim O'Neill")); 220 221 persons.push(vendorFactory.create("Gerald Watson")); 222 persons.push(vendorFactory.create("Nicole McNight")); 223 224 for (var i = 0, len = persons.length; i < len; i++) { 225 persons[i].say(); 226 } 227 228 log.show(); 229 } 230 </script> 231 </body> 232 </html>