工厂方法模式对创建同一系列产品对象的应用具有很好的支持作用,比如创建水果系列的产品,我们任意添加我们想要的产品(也即系统新功能)而不用改变原来产品及其创建形式(也即不用改变原来系统功能),但是当我们需要创建具有相关或相互依赖的对象时,工厂方法就做不到了,它不能为用户(也即使用工厂方法的人)提供统一的接口,比如:有一个水果系列产品,有一个篮子系列产品,苹果要用红色的篮子盛装(也即苹果对象与红篮子对象有相关关系),橘子要用橙色的篮子盛装,葡萄要用紫色的篮子盛装,如果利用工厂方法的话,我们可以创建两个工厂方法类,一个用于生产水果,一个用于生产篮子,用户拿到这两个工厂方法还要自己组装,使得相应的水果与对应的篮子关联起来,我们能不能更进一步地设计呢?也就是提前将水果和篮子的生产关联起来,然后由用户去任意生产他们想要的组合方式的产品,当然可以了,这就是抽象工厂模式的作用,先看结构图:
这里abstractFactory已经提前将水果和篮子进行了关联,至于做什么样的组合(比如:苹果和红篮子组合,葡萄和紫篮子组合)用户可以实现抽象工厂创建自己想要的具体工厂方法,这里给出上面结构图的代码,同时将abstractProductA视为fruit,将abstractProductB视为basket:
1 package abstrFactory; 2 public class absTest{ 3 private static AbstractFactory abFac1; 4 private static AbstractFactory abFac2; 5 public static void main(String[] args){ 6 abFac1=new ConcreteFactory1(); 7 abFac2=new ConcreteFactory2(); 8 System.out.println(abFac1.createFruit().getName()+" "+abFac1.createBasket().getColor()); 9 System.out.println(abFac2.createFruit().getName()+" "+abFac2.createBasket().getColor()); 10 } 11 12 } 13 interface Fruit{ 14 public String getName(); 15 } 16 interface Basket{ 17 public String getColor(); 18 } 19 interface AbstractFactory{ 20 public Fruit createFruit(); 21 public Basket createBasket(); 22 } 23 class ConcreteFactory1 implements AbstractFactory{ 24 public Fruit createFruit(){ 25 return new Apple(); 26 } 27 public Basket createBasket(){ 28 return new RedBasket(); 29 } 30 } 31 class ConcreteFactory2 implements AbstractFactory{ 32 public Fruit createFruit(){ 33 return new Grape(); 34 } 35 public Basket createBasket(){ 36 return new PurpleBasket(); 37 } 38 } 39 class Apple implements Fruit{ 40 public String getName(){ 41 return "Iam apple"; 42 } 43 } 44 class Grape implements Fruit{ 45 public String getName(){ 46 return "Iam grape"; 47 } 48 } 49 class RedBasket implements Basket{ 50 public String getColor(){ 51 return "Iam Red Basket"; 52 } 53 } 54 class PurpleBasket implements Basket{ 55 public String getColor(){ 56 return "Iam Purple Basket"; 57 } 58 }
那么我们什么时候会用到抽象工厂模式呢?GOF已经为我们做出了总结:
- 当你要强调一系列相关的产品对象的设计以便进行联合使用时
- 当你提供一个产品类库,而只想显示它们的接口而不是实现时
- 一个系统要独立于它的产品的创建、组合和表示时
- 一个系统要由多个产品系列中的一个来配置时
抽象工厂难以支持新种类的产品,这是因为abstractFactory已经确定了 可以被创建的产品的集合,要想支持新种类的产品就必须扩展该工厂接口。