工厂方法模式是类的创建模式,又叫虚拟构造模式(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式.
工厂方法模式的用意是定义一个创建产品的工厂接口,将实际创建工作推迟到子类中。
其实工厂方法模式是简单工厂的一种延伸,在简单工厂模式中,一个工厂类处于对产品类实例化的中心位置上,他操纵所有下面的产
品类的实例化,当每次新加一个产品类的时候都要在工厂类里面进行修改。工厂方法模式就是解决这个缺点而来的,工厂方法模式把
创建每个产品实例化的工作交给了子类去做。成为一个抽象工厂,仅负责给具体工厂子类必须实现的接口,而不接触具体实例化的细
节。这样的核心工厂类就成为了一个抽象工厂角色,这样进一步的抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角
色的情况下引进新的产品。
1.模式中包含的角色及其职责
。抽象工厂角色(Creator)
工厂方法模式的核心,任何工厂类都必须实现这个接口。
。具体工厂角色(Concrete Creato)
具体工厂类是抽象工厂的一个实现,负责实例化产品对象。
。抽象角色(product)
工厂方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
。具体产品角色
工厂方法模式所创建的具体实例对象。
在这个模式中还使用简单工厂模式中的例子,做下修改,也更清楚的区分简单工厂模式与工厂方法模式的区别。
话说华苑长华里的菜市场里面的买菜的,一个卖菜的摊主就是一个工厂角色,他卖很多种的菜,比如菜有以下三种:
○1.白菜
○2.黄瓜
○3.西红柿
这些蔬菜都有一些共同的属性,即 进货时间,产地,价钱,这样就可以建立一个蔬菜的接口,使用UML图描述如下:
蔬菜接口:有如下方法:getPurchaseDate()//获取进货日期,getOrigin()//获取蔬菜产地,getPrice()//获取价格。
使用代码清单就是:
public interface Vegetable{
/*
*获取进货日期
*
*/
public void getPurchaseDate();
/*
*获取产地
*
*/
public void getOrigin();
/*
*获取蔬菜价格
*
*/
public void getPrice();
}
接着是三个具体蔬菜类:
白菜具体蔬菜角色: 属性分为大叶白菜和卷心菜
public class Cabbage implements Vegetable {
/*
*获取进货日期
*
*/
private String daye=null;
public void getPurchaseDate(){
System.out.println(“2009-7-25”);
}
/*
*获取产地
*
*/
public void getOrigin(){
System.outprintln(“天津宝坻”);
}
/*
*获取蔬菜价格
*
*/
public void getPrice(){
System.out.println(“1.00元/千克”);
}
public void setDaye(String daye){
this.daye=daye
}
public String getDaye(){
return this.daye;
}
}
黄瓜的实体类就是 黄瓜分为白心黄瓜和绿心黄瓜
public class Cucumber implements Vegetable {
/*
*获取进货日期
*
*/
private String neiCo=null;
public void getPurchaseDate(){
System.out.println(“2009-7-26”);
}
/*
*获取产地
*
*/
public void getOrigin(){
System.outprintln(“天津大港”);
}
/*
*获取蔬菜价格
*
*/
public void getPrice(){
System.out.println(“5.00元/千克”);
}
public void setNeiCo(String neiCo){
this.neiCo=neiCo;
}
public String getNeiCo(){
return this.neiCo;
}
}
西红柿的实体类就是: 有个特殊属性是 大号西红柿,小号西红柿
public class Tomatoes implements Vegetable {
boolean bigOr=false;
/*
*获取进货日期
*
*/
public void getPurchaseDate(){
System.out.println(“2009-7-23”);
}
/*
*获取产地
*
*/
public void getOrigin(){
System.outprintln(“天津西青张家窝”);
}
/*
*获取蔬菜价格
*
*/
public void getPrice(){
System.out.println(“6.00元/千克”);
}
public void setBigOr(boolean bigOr){
this.bigOr=bigOr;
}
public boolean getBigOr(){
return this.bigOr;
}
}
工厂角色
这里的核心类就不是一个简单的进行判断逻辑的工厂类了,而是一个抽象工厂方法。
public interface VegetableFactory{
public Vegetable getVegetableObject();
}
白菜具体实例化工厂类
public class cabbageFactory implements VegetableFactory{
public Vegetable getVegetableObject(){
return (Vegetable)new Cabbage();
}
}
黄瓜具体实例化工厂类
public class CucumberFactory implements VegetableFactory{
public Vegetable getVegetableObject(){
return (Vegetable)new Cucumber();
}
}
西红柿具体实例化工厂类
public class CucumberFactory implements VegetableFactory{
public Vegetable getVegetableObject(){
return (Vegetable)new Cucumber();
}
}
客户端测试类
public class MainClass{
public static void main(String[] agrs){
//Vegetable cabbage = VegetableFactory.factory(“Cabbage”);
// Vegetable tomatoes = VegetableFactory.factory(“Tomatoes”);
// cabbage.getPrice();
// tomatoes.getPrice();
VegetableFactory cabbageFactory = new CabbageFactory();
Vegetable vegetable = cabbageFactory.getVegetableObject();
vegetable.getPrice();
VegetableFactory tomatoesFactory = new TomatoesFactory();
vegetable = tomatoesFactory.getVegetableObject();
vegetable.getPrice();
}
}
通过以上的例子你会发现在工厂方法模式跟简单工厂模式最的不同的是:工厂方法模式为每个产品类都配备了实例化工厂类,这些工厂类同样类似产品类都有一个抽象的接口,这个就是抽象工厂类。通过客户端测试类我认为才能看出工厂方法类的有点,比工厂方法类优秀的地方在测试类里才展现出来,在测试类里进行工厂类的初始化之后,在工厂方法中不必进行修改。同时测试类中的vegetable对象也不必知道自己到底是白菜还是西红柿。
在IPNMS中,在先做的主机监控功能块的提取数据和历史性能分析模块中BAS在线用户数和地址池利用率我已引入了该模式进行程序的设计,相比之下感觉自己的程序是比以前思路清晰多了,可维护性提高了,可扩展性提高了,为什么要引进来了呢,我历史性能分析本来的思路是以后往数据库里面添加任何新的指标组,我这里都能够兼容上,不过,很快我发现我错了,在兼容了温度,风扇状态以后,虽然又兼容了在线用户数和地址池利用率,但新的指标组越来越难兼容了,在电路性能的引入之后再也兼容不了,不得不走上设计模式的道路,这也许就是大师说的,编程到了一定时候自动会想到设计模式。