工厂模式
1.简单工厂:通常另外使用一个类或对象来封装实例化操作。
2.工厂模式:真正的工厂模式则是需要定义一个抽象的工厂方法并把实例化的工作推迟到子类中进行!(接口起着关键性的作用!)
下面以一个简单的例子来说明工厂模式的使用方法:假设你需要开几个Pizza店。每个Pizza店有几种不同类型的Pizza供客人选择。最初的代码可能是下面这样的。
版本1:未使用任何设计模式: 每次加入新种类的pizza,都得修改pizzaStore的代码,尽管它的工作内容并没有改变(pizzaStore只是负责订购pizza,并不负责pizza的创建)。这样显然不合情理。
<script type="text/javascript" src="00_Interface.js"></script>
<script type="text/javascript">
/**
* 定义Pizza接口,每个披萨都具有“准备”,“烘烤”,“装箱”这几个方法
* @type {Interface}
*/
var Pizza = new Interface("Pizza", ["prepare", "bake", "box"]);
/**
* 分别实现三种不同的Pizza类型
* @constructor
*/
function CheesePizza() {
}
CheesePizza.prototype = {
constructor: CheesePizza,
prepare: function () {
//实现prepare方法
}, bake: function () {
//实现bake方法
}, box: function () {
//实现box方法
}
}
function CornPizza() {
}
CornPizza.prototype = {
constructor: CornPizza,
prepare: function () {
//实现prepare方法
}, bake: function () {
//实现bake方法
}, box: function () {
//实现box方法
}
}
function PorkPizza() {
}
PorkPizza.prototype = {
constructor: PorkPizza,
prepare: function () {
//实现prepare方法
}, bake: function () {
//实现bake方法
}, box: function () {
//实现box方法
}
}
/***
* Pizza店的实现类
* @type {{orderPizza: Function}}
*/
var pizzaStore = {
orderPizza: function (type) {
var pizza;
if (type == "cheese") {
pizza = new CheesePizza();
} else if (type == "corn") {
pizza = new CornPizza();
} else if (type == "pork") {
pizza = new PorkPizza();
}
Interface.ensureImplements(pizza, [Pizza]);
pizza.prepare(); //准备
pizza.bake();//烘烤
pizza.box();//装箱
return pizza;
}
}
//var pizza = pizzaStore.orderPizza("cheese");
var pizza = pizzaStore.orderPizza("pork");
alert(pizza.constructor);
</script>
版本2:使用简单工厂:将创建pizza的代码提取到一个简单工厂中去,是这个工厂对象仅仅只是负责pizza的创建这一职责,同时新加入品种也无需再修改pizzaStore类。
1.加入创建pizza的工厂对象
//创建pizza的简单工厂
var PizzaFactory = {
createPizza: function (type) {
var pizza;
if (type == "cheese") {
pizza = new CheesePizza();
} else if (type == "corn") {
pizza = new CornPizza();
} else if (type == "pork") {
pizza = new PorkPizza();
}
Interface.ensureImplements(pizza, [Pizza]);
return pizza;
}
}
2.在pizzaStore中使用这个工厂对象来创建
var pizzaStore = {
orderPizza: function (type) {
var pizza = PizzaFactory.createPizza(type);
pizza.prepare(); //准备
pizza.bake();//烘烤
pizza.box();//装箱
return pizza;
}
}
3.其余部分保持不变
版本3:使用真正的工厂模式:真正的工厂模式与简单工厂的区别在于,它不是另外使用一个对象或类来创建实例,而是使用一个子类。按照正式定义:工厂是一个将其成员对象的实例化延迟到子类中进行的类。
<script type="text/javascript" src="00_Interface.js"></script>
<script type="text/javascript">
/**
* 定义Pizza接口,每个披萨都具有“准备”,“烘烤”,“装箱”这几个方法
* @type {Interface}
*/
var Pizza = new Interface("Pizza", ["prepare", "bake", "box"]);
//假设你的pizza店有2个分店,位于三个不同的地区,分别生产当地口味的pizza
//首先定义一个抽象基类,PizzaStore
var PizzaStore = function () {
};
PizzaStore.prototype = {
constructor: PizzaStore,
orderPizza: function (type) {
var pizza = this.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.box();
return pizza;
}, createPizza: function (type) {
throw new Error("抽象类中未实现该方法,在具体子类中实现!");
}
}
//湖南分店:口味偏辣
function HuNanPizzaStore() {
PizzaStore.call(this, arguments);
}
;
//继承基类
HuNanPizzaStore.prototype = new PizzaStore();
HuNanPizzaStore.prototype.constructor = HuNanPizzaStore;
HuNanPizzaStore.prototype.createPizza = function (type) {
var pizza;
if (type == "greenPepper") {
pizza = new GreenPepperPizza(); //具体Pizza类的实现省略...
} else if (type == "redPepper") {
pizza = new RedPepperPizza();//具体Pizza类的实现省略...
}
Interface.ensureImplements(pizza, [Pizza]);
return pizza;
}
//上海分店,口味偏甜
function ShangHaiPizzaStore() {
PizzaStore.call(this, arguments);
}
ShangHaiPizzaStore.prototype = new PizzaStore();
ShangHaiPizzaStore.prototype = {
constructor: ShangHaiPizzaStore,
createPizza: function (type) {
var pizza;
if (type == "tomato") {
pizza = new TomatoPizza(); //具体Pizza类的实现省略...
} else if (type == "pineapple") {
pizza = new PineapplePizza();//具体Pizza类的实现省略...
}
Interface.ensureImplements(pizza, [Pizza]);
return pizza;
}
}
//使用
var pizzaStore;
pizzaStore = new HuNanPizzaStore();
pizzaStore.orderPizza("greenPepper"); //从湖南分店订购青椒披萨
pizzaStore = new ShangHaiPizzaStore();
pizzaStore.orderPizza("pineapple"); //从上海分店订购凤梨披萨
</script>
使用真正的工厂模式后,想增加其他的分店很简单,只需要增加一个PizzaStore的子类,并实现其createPizza方法即可,不会对其他类造成任何影响!也可以对各个子类进行修改,以增加不同食材的pizza。这是工厂模式最重要的特点。对pizza进行的一般性操作可以放在抽象父类PizzaStore中,而其他具体的实现则放在对应的子类中实现!
版权声明:本文为博主原创文章,未经博主允许不得转载。