代码改变世界

创建类模式(二):抽象工厂(Abstract Factory)

2016-10-27 13:36  阿诚de窝  阅读(333)  评论(0编辑  收藏  举报

定义

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。

产品族

抽象工厂模式中,引入了产品族的概念,什么是产品族呢?

比如轿车和SUV这两种类型的汽车,属于两种不同类型的结构(即产品等级结构),而奔驰和宝马这两个汽车制造品牌,则属于两种不同的品牌,而这里的品牌我们就可以看做产品族的概念。

奔驰和宝马毫无疑问的都会生产轿车和SUV,那么奔驰轿车和宝马轿车、奔驰SUV和宝马SUV属于两个不同类型的结构(即不同的产品等级结构),而奔驰轿车和奔驰SUV、宝马轿车和宝马SUV属于两个不同类型的产品族。

和工厂方法模式的区别

  1. 每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。
  2. 即如果工厂的产品全部属于同一个等级结构,则属于工厂方法模式;如果工厂的产品来自多个等级结构,则属于抽象工厂模式。
  3. 还是以上面的例子来看:如果一个工厂根据不同的参数提供奔驰轿车和宝马轿车,则他属于工厂方法模式,因为其提供的是同一个接口下同一个等级结构的对象;而如果一个工厂提供奔驰轿车和奔驰SUV,那么这个工厂模式就是抽象工厂模式,因为他提供的产品是分属两个不同的接口下的不同的等级结构对象。

UML

优点

  1. 抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建。
  2. 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
  3. 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。

缺点

  1. 增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。

应用场景

  1. 系统不依赖于产品类实例如何被创建,组合和表达的细节;
  2. 系统的产品有多于一个的产品族,而系统只消费其中某一族的产品;
  3. 同属于同一个产品族是在一起使用的。这一约束必须在系统的设计中体现出来;
  4. 系统提供一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖于实现。

示例

一个简单的奔驰和宝马生产流水线。

Java

  1 public class Main
  2 {
  3     public static void main(String[] args)
  4     {
  5         IFactory factory;
  6         //奔驰流水线开动了
  7         factory = new BenzFactory();
  8         factory.createSaloon().startEngine();
  9         factory.createSUV().startEngine();
 10         //宝马流水线开动了
 11         factory = new BmwFactory();
 12         factory.createSaloon().startEngine();
 13         factory.createSUV().startEngine();
 14     }
 15     
 16     /**
 17      * 轿车接口
 18      */
 19     public static interface ISaloonCar
 20     {
 21         public void startEngine();
 22     }
 23 
 24     /**
 25      * SUV接口
 26      */
 27     public static interface ISUVCar
 28     {
 29         public void startEngine();
 30     }
 31 
 32     /**
 33      * 奔驰轿车
 34      */
 35     public static class BenzSaloonCar implements ISaloonCar
 36     {
 37         public void startEngine()
 38         {
 39             System.out.println("奔驰轿车发动了!");
 40         }
 41     }
 42 
 43     /**
 44      * 奔驰SUV
 45      */
 46     public static class BenzSUVCar implements ISUVCar {
 47         public void startEngine() {
 48             System.out.println("奔驰SUV发动了!");
 49         }
 50     }
 51 
 52     /**
 53      * 宝马轿车
 54      */
 55     public static class BmwSaloonCar implements ISaloonCar
 56     {
 57         public void startEngine()
 58         {
 59             System.out.println("宝马轿车发动了!");
 60         }
 61     }
 62 
 63     /**
 64      * 宝马SUV
 65      */
 66     public static class BmwSUVCar implements ISUVCar
 67     {
 68         public void startEngine()
 69         {
 70             System.out.println("宝马SUV发动了!");
 71         }
 72     }
 73 
 74     /**
 75      * 汽车生产线工厂接口
 76      */
 77     public static interface IFactory
 78     {
 79         ISaloonCar createSaloon();
 80         
 81         ISUVCar createSUV();
 82     }
 83 
 84     /**
 85      * 奔驰牌轿车工厂
 86      */
 87     public static class BenzFactory implements IFactory
 88     {
 89         public ISaloonCar createSaloon()
 90         {
 91             return new BenzSaloonCar();
 92         }
 93         
 94         public ISUVCar createSUV()
 95         {
 96             return new BenzSUVCar();
 97         }
 98     }
 99 
100     /**
101      * 宝马牌轿车工厂
102      */
103     public static class BmwFactory implements IFactory
104     {
105         public ISaloonCar createSaloon()
106         {
107             return new BmwSaloonCar();
108         }
109         
110         public ISUVCar createSUV()
111         {
112             return new BmwSUVCar();
113         }
114     }
115 }
View Code