之前的3种工厂模式中,核心都是工厂类,一个工厂类承担了所有产品的创建工作,如果产品的树形结构需要扩展,就必须在工厂类中为新增的产品增加创建功能,这显然违背了开闭原则----在扩展时不能够修改原来的代码。
为了解决这个问题,我们可以采用抽象工厂模式,即建立与产品类等级相似的工厂等级结构,为每一个产品都提供一个具体的工厂类。
首先创建一个工厂类的接口,它提供了一个接口方法produce()用来创建一个产品,代码如下:
●抽象工厂模式父类
●创建三个工厂类
这样,我们在需要创建三种产品时,只创建对应产品的工厂类来创建各自的产品对象即可,测试程序如下:
●何时使用抽象工厂模式
根据以上的扩展讲解可知,抽象工厂适用于产品结构多变或有可能扩展的产品创建中,但实际上,我们大多数的程序都需要给未来的维护留下有扩展的余地,这才符合开闭原则。所以大多数时候,我们都会采用抽象工厂模式。当然这并不表示普通的工厂方法没有适用的场景,如果产品结构比较固定也比较简单,则可以使用,就好比上一节中Swing的工厂BorderFactory所示。
为了解决这个问题,我们可以采用抽象工厂模式,即建立与产品类等级相似的工厂等级结构,为每一个产品都提供一个具体的工厂类。
首先创建一个工厂类的接口,它提供了一个接口方法produce()用来创建一个产品,代码如下:
●抽象工厂模式父类
public interface Farm{
public Animal produce();
}
●创建三个工厂类
//Pig工厂类
public class FarmPig implements Farm{
public Animal produce(){
return new Pig();
}
}
//Chicken工厂类
public class FarmChicken implements Farm{
public Animal produce(){
return new Chicken();
}
}
//Sheep工厂类
public class FarmSheep implements Farm{
public Animal produce(){
return new Sheep();
}
}
这样,我们在需要创建三种产品时,只创建对应产品的工厂类来创建各自的产品对象即可,测试程序如下:
public class FarmTest{
public static void test(int count1,int count2,int count3){
//生产猪
Farm farm1 = new FarmPig();
Animal animal1 = farm1.produce();
//生产鸡
Farm farm2 = new FarmChicken();
Animal animal2 = farm2.produce();
//生产羊
Farm farm3 = new FarmSheep();
Animal animal3 = farm3.produce();
//计算收入
int money1 = animal1.sale()*count1;
int money2 = animal2.sale()*count2;
int money3 = animal3.sale()*count3;
System.out.println("Farm养猪收入:" + money1);
System.out.println("Farm养鸡收入:" + money2);
System.out.println("Farm养羊收入:" + money3);
//计算总收入
int sum = money1 + money2 + money3;
System.out.println("Farm总收入:" + sum);
}
public static void main(String[] args){
FarmTest.test(20,1000,50);
}
}
●何时使用抽象工厂模式
根据以上的扩展讲解可知,抽象工厂适用于产品结构多变或有可能扩展的产品创建中,但实际上,我们大多数的程序都需要给未来的维护留下有扩展的余地,这才符合开闭原则。所以大多数时候,我们都会采用抽象工厂模式。当然这并不表示普通的工厂方法没有适用的场景,如果产品结构比较固定也比较简单,则可以使用,就好比上一节中Swing的工厂BorderFactory所示。