工厂模式
工厂模式是软件工程领域一种广为人知的设计模式,也叫虚拟构造函数模式,主要用于创建对象。
工厂模式可以分为简单工厂模式和工厂方法模式。
简单工厂模式
正常情况下,我们通过类的实例化来创建对象:
例子:
/* JavaScript类 */
var JavaScript = function(text) {
this.text = text;
JavaScript.prototype.showText = function() {
return this.text;
}
}
/* 创建对象 */
var JavaScriptAD = new JavaScript("JavaScript是前端开发语言!");
上例存在的最大问题是:如果引入新的类,那么实例化这个新类时就要调用对应类的构造函数。
例子:
/* JavaScript类 */
var JavaScript = function(text) {
this.text = text;
JavaScript.prototype.showText = function() {
return this.text;
}
}
/* 新引入Java类 */
var Java = function(text) {
this.text = text;
Java.prototype.showText = function() {
return this.text;
}
}
/* 调用JavaScript类的构造函数,创建对象 */
var JavaScriptAD = new JavaScript("JavaScript是前端开发语言!");
/* 调用Java类的构造函数,创建对象 */
var JavaAD = new Java("Java是后端开发语言!");
类似情况出现时,理想的方法是使用简单工厂模式将创建对象的过程封装在一个函数里,由这个函数决定哪一个类应该去实例化(利用多态性)。
例子:
/* JavaScript类 */
var JavaScript = function(text) {
this.text = text;
JavaScript.prototype.showText = function() {
return this.text;
}
}
/* 新引入Java类 */
var Java = function(text) {
this.text = text;
Java.prototype.showText = function() {
return this.text;
}
}
/* 简单工厂模式 */
/* 工厂函数 */
var factory = function(key) {
switch (key) {
case "JavaScript":
return new JavaScript("JavaScript是前端开发语言!");
break;
case "Java":
return new Java("Java是后端开发语言!");
break;
}
}
/* 创建对象 */
var JavaScriptAD = factory("JavaScript");
var JavaAD = factory("Java");
工厂函数 factory 就相当于“构造函数”,通过这个函数就可以创建我们所需要的对象,无需找到对应的类。
上例中的两个类,包含的属性和方法基本一致,创建这种多个相似对象时,我们也可以直接使用工厂函数去创建。
例子:
/* 简单工厂模式 */
/* 工厂函数 */
var factory = function(text) {
var obj = {};
obj.text = text;
obj.showText = function() {
return this.text;
}
return obj;
}
/* 创建对象 */
var JavaScriptAD = factory("JavaScript是前端开发语言!");
var JavaAD = factory("Java是后端开发语言!");
工厂方法模式
简单工厂模式虽然解决了创建对象的问题,但其缺点也很明显:每次有新的类加入时,都必须在工厂函数中加入相应的逻辑。工厂方法模式就是对简单工厂的进一步抽象与优化。
工厂方法模式的核心是:工厂函数本身不再负责实例化对象,而是将实际创建的工作交给子类去完成。
JavaScript 中生搬硬套工厂方法模式的定义并没有多大意义,因此我们只考虑它的核心思想即可,也就是工厂函数本身不再创建对象,仅负责提供接口,而交由谁去创建对象,则可以根据 JavaScript 语言的特点而定,一般会选择原型对象。
例子:
/* 工厂方法模式 */
/* 工厂函数 */
var Factory = function(type, text) {
if (this instanceof Factory) {
return new this[type](text);
}
return new Factory(type, text);
}
//创建对象的方法写在工厂函数的原型里
Factory.prototype = {
JavaScript: function(text) {
this.text = text;
this.showText = function() {
return this.text;
}
},
Java: function(text) {
this.text = text;
this.showText = function() {
return this.text;
}
}
}
/* 创建对象 */
var JavaScriptAD = new Factory("JavaScript", "JavaScript是前端开发语言!");
var JavaAD = new Factory("Java", "Java是后端开发语言!");
重构后,如果我们想添加新类,写在工厂函数的原型里即可,工厂函数本身无需做任何修改。
如有错误,欢迎指正,本人不胜感激。