定义
为创建一组相关或相互关联的对象提供一个接口,而无需指定它们的具体类。
事例
在农场产品中,有水果(Fruit)和蔬菜(Veggie)两种产品分类,这两种产品分别有北方(Northern)、热带(Tropical)两种分类,即总共有四种具体产品:
Fruit{NorthernFruit ,TropicalFruit}
Veggie{NortherVeggie,TropicalVeggie}
当我们用具体工厂去生产具体实例产品时,因每个抽象产品(Fruit|Veggie)都有多于一个的具体子类,工厂角色怎么知道实例化哪一个子类呢?在这里我们就要用的最为抽象和最具一般性的一种工厂模式:抽象工厂模式!
每一种模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式针对的是多个产品等级结构。
抽象工厂模式解决的是多个等级、相同结构的产品族的创建问题,以上事例可用以下二维图表示:
抽象工厂模式的优点
抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。
抽象工厂模式的缺点
产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。但是一定要清楚是产品族扩展困难,而不是产品等级,在该模式下,产品等级是非常容易扩展的,增加一个产品等级,只要增加一个工厂类负责新增加出来的产品生产任务即可,也就是说横向扩展容易,纵向扩展困难。
代码设计如下:
package bean;
public abstract class Fruit {
public Fruit() {
System.out.println("this is a Fruit.");
}
}
package bean;
public class NorthernFruit extends Fruit {
public NorthernFruit() {
System.out.println("this is a northernFruit");
}
}
package bean;
public class TropicalFruit extends Fruit {
public TropicalFruit() {
System.out.println("this is a tropicalFriut.");
}
}
package bean;
public abstract class Veggie {
public Veggie() {
System.out.println("this is a veggie.");
}
}
package bean; public class TropicalVeggie extends Veggie { public TropicalVeggie() { System.out.println("this is a tropicalVeggie."); } }
package bean; public class NorthernVeggie extends Veggie { public NorthernVeggie() { System.out.println("this is a northernVeggie."); } } package factory; import bean.Fruit; import bean.Veggie; public interface Gardener { Fruit createFruit(); Veggie creaeVeggie(); } package factory; import bean.Fruit; import bean.NorthernFruit; import bean.NorthernVeggie; import bean.Veggie; public class NorthernGardener implements Gardener { public Fruit createFruit() { return new NorthernFruit(); } public Veggie creaeVeggie() { return new NorthernVeggie(); } } package factory; import bean.Fruit; import bean.TropicalFruit; import bean.TropicalVeggie; import bean.Veggie; public class TropicalGardener implements Gardener { public Veggie creaeVeggie() { return new TropicalVeggie(); } public Fruit createFruit() { return new TropicalFruit(); } }