设计模式-工厂模式
2017-05-25 本文已影响104人
你期待的花开
工厂模式概念
实例化对象,用工厂方法代替new操作。
工厂模式包括工厂方法模式和抽象工厂模式。
抽象工厂模式是工厂模式的扩展。
工厂模式的意图
定义一个接口来创建对象,但是让子类来决定哪些类需要被实例化。
工厂方法把实例化的工作推迟到子类中去实现。
什么情况下适合工厂模式?
工厂方法模式类图 抽象工厂模式类图有一组类似的对象需要创建
在编码时不能预见需要创建哪种类的实例
系统需要考虑扩展性,不应依赖于产品类实例如何被创建,组合和表达的细节
通过工厂方法创建的对象在设计上都继承了相同父对象的思想,它们都是实现专门功能的特定子类。有时候公共父类是一个包含了工厂方法的同一个类。
让我们看一个实现示例:
//父构造函数
function CarMaker() {
}
CarMaker.prototype.drive = function () {
console.log("I have " + this.doors + " doors");
};
//静态工厂方法
CarMaker.factory = function (type) {
var constr = type,
newcar;
//如果构造函数不存,则发生错误
if (typeof CarMaker[constr] !== "function") {
throw{
name: "Error",
message: constr + "doesn't exist"
};
}
//在这里,构造函数是已知存在的
//我们使得原型继承父类,但仅继承一次
if (typeof CarMaker[constr].prototype.drive !== "function") {
CarMaker[constr].prototype = new CarMaker();
}
//创建一个新的实例
newcar = new CarMaker[constr]();
//可选择性的调用一些方法,然后返回...
return newcar;
};
//定义特定的汽车制造商
CarMaker.Compact = function () {
this.doors = 4;
};
CarMaker.Convertible = function () {
this.doors = 2;
};
CarMaker.SUV = function () {
this.doors = 24;
};
var corolla = CarMaker.factory('Compact');
var solstice = CarMaker.factory('Convertible');
var cherokee = CarMaker.factory('SUV');
corolla.drive();
solstice.drive();
cherokee.drive();
打印结果示意图
在这个实例中
- 公共父构造函数CarMarker。
- 一个名为factory()的CarMarker的静态方法,该方法创建了car对象。
- 从CarMarker继承的专门构造函数 CarMaker.Compact、CarMaker.Convertible和CarMaker.SUV。所有这些构造函数都被定义为父类的静态属性,以便保证全局命名空间免受污染,因此我们也知道了当需要这些构造函数的时候可以在哪里找到它们。
- 其中
var corolla = CarMaker.factory('Compact');
可能是工厂模式最容易辨别的部分。现在看到的工厂方法接受在运行时以字符串形式指定的类型,然后创建并返回所请求类型对象。代码中看不到任何具有new或对象字面量的构造函数,其中仅有一个函数根据字符串所指定类型来创建对象。