前面文章中的3种工厂方法模式中,核心都是工厂类,一个工厂类承担了所有产品的创建工作,如果产品的树形结构需要扩展,就必须在工厂类中为新增的产品增加创建功能,这显然违背了开闭原则–在扩展时不能够修改原有的代码。
为了解决这个问题,我们可以采用抽象工厂模式,即建立与产品类等级相似的工厂等级结构,为每一个产品都提供一个具体的工厂类,如下图所示。
这样,如果要扩展增加一个新的产品,只需要增加一个新的工厂类即可。同时,如果产品类中出现了多层继承,也可以在工厂类中进行多层继承。
在以上的结构中,首先需要创建一个工厂类的接口,它提供了一个接口方法produce0用来创建个产品,如下程序 所示:
package creation.abstractfactory;
/**
* @author Minggg
* 抽象工厂模式
*/
public interface Farm4 {
public Animal produce();
}
分别实现4个产品的工厂类:
1)Pig工厂Farm4Pig.java
创建 Pig 的工厂类,如下程序所示:
抽象工厂模式具体类 Farm4Pig.java
package creation.abstractfactor;
public class Farm4Pig implements Farm4 {
public Animal produce(){
return new Pig();
}
}
2)Chicken 工Farm4Chicken.iava
创建 Chicken 的工厂类,如下程序所示:
抽象工厂模式具体类Farm4Chicken.java
package creation.abstractfactory;
public class Farm4Chieken implements Farm4{
publie Animal produce(){
return new Chicken();
}
}
3)Cattle 厂Farm4Cattle.iava
创建 Cattle的工厂类,如下程序所示:
抽象工厂模式具体类 Farm4Cattle .java
package creation.abstractfactory;
public class Farm4Cattle implements Farm4 {
public Animal produce(){
return new Cattle();
}
}
4)Sheep 工厂Farm4Sheep.java
创建 Sheep 的工厂类,如下程序所示:
抽象工厂模式具体类 Farm4Sheep .java
package creation.abstractfactory;
public class Farm4Sheep implements Farm4 {
public Animal produce(){
return new Sheep();
}
}
这样,我们在需要创建4种产品时,只创建对应产品的工厂类来创建各自的产品对象即可,测试程序如下所示:
测试类Farm4Test.java
package creation.abstractfactory;
public class Farm4Test {
public static void test(int countl, int count2, int count3, int count4){
// 生产猪
Farm4 farm1 = new Farm4Pig();
Animal animal1 = farm1.produce();
//生产鸡
Farm4 farm2 = new Farm4Chicken();
Animal animal2 = farm2.produce();
// 生产牛
Farm4 farm3 = new Farm4Cattle();
Animal animal3 = farm3.produce();
// 生产羊
Farm4 farm4 = new Farm4Sheep();
Animal animal4 = farm4.produce();
//计算收入
int moneyl = animall.sale()* countl;
int money2 = animal2.sale()* count2;
int money3 = animal3.sale()* count3;
int money4 = animal4.sale()* count4;
System.out,println("Fram4 养猪收入:"+ money1);
System.out.println("Fram4 养鸡收入:"+ money2);
System.out.println("Fram4 养牛收入:"+ money3);
System.out.println("Fram4 养羊收入:"+ money4);
//计算总收入
int sum = moneyl + money2 + money3 + money4;
System.out.println("Fram4总收入:"+ sum);
}
public static void main(String[] args) {
Farm4Test.test(20,1000,10,50);
}
}
根据以上的扩展讲解可知,抽象工厂适用于产品结构多变或有可能扩展的产品创建中。但实际上,我们大多数的程序都需要给未来的维护留有扩展的余地,这才符合开闭原则。所以大多数时候,我们都会采用抽象工厂模式。当然这并不表示普通的工厂方法没有适用的场合,如果产品结构比较固定也比较简单,则可以使用,就好比方法工厂章节中Swing的工厂BorderFactory 所示。