工厂方法模式

前言

今天自己看了一下自己写的部分博客,发现写的好丑....開始注意自己的排版!!可是偏亮也不是一朝一夕就完毕的,我尽量让它美丽一点.....每天美丽一点点

 

 

正文

工厂方法模式是一种实现”工厂”概念的面向对象设计模式.实质是定义一个创建对象的接口,可是让实现这个接口的类来决定实例化哪个类.工厂方法让类的实例化推迟到子类中进行.

创建一个对象经常须要复杂的过程,所以不适合在一个复杂的对象中.创建对象可能会导致大量的反复代码,也可能提供不了足够级别的抽象.工厂方法模式通过定义一个单独的创建对象的方法来解决这些问题,由子类实现这种方法来创建详细类型的对象.

//几个Button类
class Button{/* ...*/}
class WinButton extends Button{/* ...*/}
class MacButton extends Button{/* ...*/}
 
//它们的工厂类
interface ButtonFactory{
    abstract Button createButton();
}
class WinButtonFactory implements ButtonFactory{
    Button createButton(){
        return new WinButton();
    }
}
 
class MacButtonFactory implements ButtonFactory{
    Button createButton(){
        return new MacButton();
    }
}


 

 

JS中创建对象会习惯的使用newkeyword和类构造函数(淡然主要还是对象字面量),问题在于这样会导致两个类之间产生依赖性.

工厂模式就是一种又处于消除两个类依赖性的模式.

简单工厂模式:使用一个类(通常为单体)来生成实例

复杂工厂类:使用子类来决定一个变量成员应该为哪个详细的类的实例.

 

 

 

实例1:简单工厂模式

对于自行车商店出售自行车

var BicycleShop=function(){};
	BicycleShop.prototype={
		sellBicycle:function (model){
			var bicycle;
			switch(model){
				case "A"://A类型的自行车
				bicycle=new A();
				break;
				case "B":
				bicycle=new B();
				break;
				case "C":
				bicycle=new C();
				break;
			}
  Interface.ensureImplements(bicycle,Bicycle);					return bicycle;
		}
	}




分析:

sellBicycle方法依据所提示的的自行车型号来进行自行车的实例创建.各种型号的自行车实例能够互换使用,由于他们都实现了Bicycle接口.

注意:接口在工厂模式中起着非常关键的数据.假设部队对象进行某种类型检查以确保事实上现了必需的方法,工厂模式带来的优点也就所剩无几了.

那么对于ABC这家店铺来说,我须要它的A车型,那么我仅仅须要

var ABC=new BicycleShop();
var myBike=ABC.sellBicycle(“A”);


 

以上方式非常管用,可是一但说我须要加入一些自行车款式的时候,比方我想能生产D类型的自行车,这就须要我改动BicycleShopswitch部分,那么仅仅要是改动就有可能带来BUG.所以,将这部分生成实例的代码提出来交给一个简单的工厂对象是一个非常不错的方法.

 

var BicycleFactory={
	createBicycle:function(model){
		var bicycle;
		switch(model){
			case "A":
			bicycle=new A();
			break;
			case "B":
			bicycle=new B();
			break;
			case "C":
			default:
			bicycle=new C();
			break;
			}
			return bicycle;
	}
}





BicycleFactory是一个脱离于BicycleShop的单体.用来把createBicycle方法封装在一个命名空间中.BicycleFactory返回一个实现了Bicycle接口的对象.当须要加入新的类型的时候,不须要懂BicycleShop仅仅须要改动工厂单体对象就能够:

var BicycleShop=function (){};
	BicycleShop.prototype={
		sellBicycle:function(model){
			var bicycle=BicycleFactory.createBicycle(model);
			return bicycle;
		}
	}




 

以上就是一个非常好的简单工厂的实例.该模式将成员对象的创建工作交给一个外部对象实现,该外部对象能够是一个简单的命名空间,也能够是一个类的实例.

 

 

 

 

 

 

实例2:工厂模式

真正的工厂模式与简单工厂模式对照,主要差别就是它不是另外使用一个对象或者类来创建实例(自行车),而是使用一个子类.工厂是一个将其成员对象的实例化推迟到子类中进行的类.

 

比方BicycleShop能够决定从那一家厂商进行进货,那么简单的一个BicycleFactory是不够的,由于各个厂商会各自生产不同型号的自行车,所以首先须要生成各自厂商的shop实例,不同厂商的shop实例拥有不同的生成几个型号自行车的方法.

 

也就是相当于将自行车对象的实例化推迟到了shop实例中产生.

基础:

</pre><p><pre name="code" class="javascript">var BicycleShop=function (){};
	BicycleShop.prototype={
		sellBicycle:function(model){
			var bicycle=BicycleFactory.createBicycle(model);
			return bicycle;
		},
		createBicycle:function(model){
			throw new Error("在使用类不支持的操作");
		}	
	}




这个类定义了createBicycle方法,但真要调用这种方法的话,会抛出一个错误.如今BicycleShop是一个抽象类,他不能被实例化,仅仅能用来派生子类.设计一个经销特定自行车生产厂家产品的子类须要扩展BicycleShop,重定义当中的createBicycle方法.

各自厂商:

var ABicycleShop=function(){};
	extend(ABicycleShop,BicycleShop);
	ABicycleShop.prototype.createBicycle=function(model){
		var dicycle;
		switch(model){
			case "A":
			bicycle=new A();
			break;
			case "B":
			bicycle=new B();
			break;
			case "C":
			default:
			bicycle=new C();
			break;
		}
			return bicycle;
	}
		
	var BBicycleShop=function(){};
	extend(BBicycleShop,BicycleShop);
	BBicycleShop.prototype.createBicycle=function(model){	
	var dicycle;
		switch(model){
			case "A":
			bicycle=new A();
			break;
			case "B":
			bicycle=new B();
			break;
			case "C":
			default:
			bicycle=new C();
			break;
		}
			return bicycle;
	}




那么接下来就非常easy了,对于来自A厂商的货

var aShop=new ABicycleShop();

var newBicycle=aShop.sellBicycle(“A”);

 

当然,你也能够对于外层生成的子类实例在使用简单工厂模式进行包装一下,对于加入其它厂商也非常easy,再创建一个Bicycle的子类重定义其createBicycle的工厂方法就可以.

 

 

 

工厂模式使用场合

1.动态实现

比如自行车的样例,创建一些用不同方式实现统一接口的对象,那么能够使用一个工厂方法或者简单工厂对象来简化实现过程.选择能够是明白进行的也能够是隐含的.

 

2.节省开销

假设对象要进行复杂的而且批次相关的设置的时候,那么工厂模式能够显著的降低每种队形的代码量.将特定的设置代码提取出来会使得代码有极大的提升.而且能优化结构便于维护.

 

3.用于很多小型对象组成一个大对象

 

4使用工厂模式的优缺点

优点是能够消除对象见的耦合,通过使用project方法而不是new keyword.将全部实例化的代码集中在一个位置房子代码反复.

缺点是大多数类最好使用newkeyword和构造函数,能够让代码更加简单易读.而不必去查看工厂方法来知道.