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>