工厂模式
Factory pattern
知识点一:定义
定义一个工厂方法(生产者)返回一个实例对象(产品),最终让一个子类(实际生产者)去完成实例化(生产产品)。工厂模式甚至允许不使用一个构造函数,就可以提供一个通用接口来创建对象。
知识点二:具体例子
//定义工厂
function Factory() {
this.createEmployee = function (type) {
var employee;
if (type === "fulltime") {
employee = new FullTime();
} else if (type === "parttime") {
employee = new PartTime();
} else if (type === "temporary") {
employee = new Temporary();
} else if (type === "contractor") {
employee = new Contractor();
}
employee.type = type;
employee.say = function () {
log.add(this.type + ": rate " + this.hourly + "/hour");
}
//生成ConcreteProduct实例
return employee;
}
}
//定义ConcreteProduct产品类
var FullTime = function () {
this.hourly = "$12";
};
var PartTime = function () {
this.hourly = "$11";
};
var Temporary = function () {
this.hourly = "$10";
};
var Contractor = function () {
this.hourly = "$15";
};
// log helper
var log = (function () {
var log = "";
return {
add: function (msg) { log += msg + "\n"; },
show: function () { alert(log); log = ""; }
}
})();
function run() {
var employees = [];
var factory = new Factory();
employees.push(factory.createEmployee("fulltime"));
employees.push(factory.createEmployee("parttime"));
employees.push(factory.createEmployee("temporary"));
employees.push(factory.createEmployee("contractor"));
for (var i = 0, len = employees.length; i < len; i++) {
employees[i].say();
}
log.show();
}
例子分析
Creator 工厂,例子中的Factory 1. 此工厂实例可以生成不同种类的产品 1. 实现了一个工厂方法(factoryMethod)返回产品
AbstractProduct 抽象产品,例子中没使用 1. 声明产品的统一接口
ConcreteProduct 具体产品,JavaScript没有此概念 1. 被生产出来的产品 1. 所有的产品都会含有统一的接口(相同的属性或者方法)
假设有一个工厂,可以生成不同种类的工人。每一个工人有不同的时薪。createEmployee方法就是一个工厂方法。试想象一些客户端就是客户,按照不同的需要添加参数,通过调用createEmployee进行下单。工厂就会内部去实现创造一个工人实例出来。需要注意的是,由于JavaScript不支持抽象类概念,这些FullTime、PartTime等子类需要一个统一的接口(属性或者方法,例如本事例的this.hourly)。当不同种类的工人创建出来,工厂还会统一实现一些方法,例如(employee.type、employee.say)。
知识点三:特点
对以下使用场景特别有用&优点: 1. 当对象或组件设置比较复杂 1. 需要根据不同的环境生产不同的实例 1. 需要处理很多具有相同属性的小型对象或组件
什么情况下不应该使用&缺点: 1. 如果要实现的具体产品不具有统一的接口,使用此模式会带来很多不必要的复杂性。建议使用显式构造函数,减少不必要开销。 1. 由于对象创建的过程隐藏在接口之后抽象出来,单元测试可能会带来不便,这取决于创建过程的复杂性
抽象工厂(Abstract Factory)模式
知识点一:定义
提供一个接口(抽象工厂类)用来新建一些相似的有关联的或者互相依赖的对象(产品族),而不是通过一个明确指定的具体类
知识点二:具体例子
// Types.js - Constructors used behind the scenes
// A constructor for defining new cars
class Vehicle {
constructor(){
this.steering = 'left'
}
}
class Car extends Vehicle{
constructor(options){
// some defaults
this.doors = options.doors || 4;
this.state = options.state || "brand new";
this.color = options.color || "silver";
}
}
// A constructor for defining new trucks
class Truck extends Vehicle{
constructor(options){
this.state = options.state || "used";
this.wheelSize = options.wheelSize || "large";
this.color = options.color || "blue";
}
}
var abstractVehicleFactory = (function () {
// Storage for our vehicle types
var types = {};
return {
getVehicle: function ( type, customizations ) {
var _vehicle = types[type];
return (_vehicle ? new Vehicle(customizations) : null);
},
registerVehicle: function ( type, _vehicle ) {
var proto = Vehicle.prototype;
// only register classes that fulfill the vehicle contract
if ( proto.drive && proto.breakDown ) {
types[type] = _vehicle;
}
return abstractVehicleFactory;
}
};
})();
// Usage:
abstractVehicleFactory.registerVehicle( "car", Car );
abstractVehicleFactory.registerVehicle( "truck", Truck );
// Instantiate a new car based on the abstract vehicle type
var car = abstractVehicleFactory.getVehicle( "car", {
color: "lime green",
state: "like new" } );
// Instantiate a new truck in a similar manner
var truck = abstractVehicleFactory.getVehicle( "truck", {
wheelSize: "medium",
color: "neon yellow" } );
例子分析
AbstractFactory 抽象工厂:abstractVehicleFactory 1. 声明一个接口用于生产产品
concreteFactory 具体工厂:registerVehicle方法 1. 根据条件生产产品
Products 产品类:Car、Truck 1. 提供要生产产品的接口给工厂
AbstractProduct 抽象产品类:Vehicle 1. 为产品族声明接口