每天一个设计模式(6):抽象工厂模式

6.抽象工厂模式

  抽象工厂模式是对象的创建模式,它是工厂方法模式的进一步推广。通过使用抽象工厂模式,可以处理具有相同(或者相似)等级结构中的多个产品族中的产品对象的创建问题。

  抽象工厂:多个抽象产品类,派生出多个具体产品类;一个抽象工厂类,派生出多个具体工厂类;每个具体工厂类可创建多个具体产品类的实例。这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。

一.UML关系图二.实现代码

 1 //定义不同的产品之间的一定具备的标准,用interface实现 
 2 //其中的method()方法可看作提取出不同产品的共性,如手机都有类似的功能 
 3 interface IProductA{ 
 4   public void method(); 
 5 } 
 6 
 7 interface IProductB{ 
 8   public void method(); 
 9 } 
10 
11 //实现了产品标准实现的一系列具体产品 
12 //由于已经设计好A1由厂商1生产,故以下输出代码有“厂商x” 
13 class ProductA1 implements IProductA{ 
14   public void method() { 
15     System.out.println("厂商1    生产ProductA1 ..."); 
16   } 
17 } 
18 
19 class ProductA2 implements IProductA{ 
20   public void method() { 
21     System.out.println("厂商2    生产ProductA2 ..."); 
22   } 
23 } 
24 
25 class ProductB1 implements IProductB{ 
26   public void method() { 
27     System.out.println("厂商1    生产ProductB1 ..."); 
28   } 
29 } 
30 
31 class ProductB2 implements IProductB{ 
32   public void method() { 
33     System.out.println("厂商2    生产ProductB2 ..."); 
34   } 
35 } 
36 
37 //每一种牌子的产品生产工厂,即不同的厂商负责自己牌子产品的生产 
38 abstract class Factory1{ 
39   abstract IProductA getProductA1(); 
40   abstract IProductB getProductB1(); 
41 } 
42 
43 abstract class Factory2{ 
44   abstract IProductA getProductA2(); 
45   abstract IProductB getProductB2(); 
46 } 
47 
48 //具体的工厂用来生产相关的产品 
49 class ConcreteFactory1 extends Factory1{ 
50   public IProductA getProductA1() { 
51     return new ProductA1(); 
52   } 
53   public IProductB getProductB1() { 
54     return new ProductB1(); 
55   } 
56 } 
57 
58 class ConcreteFactoryB extends Factory2{ 
59   public IProductA getProductA2() { 
60     return new ProductA2(); 
61   } 
62   public IProductB getProductB2() { 
63     return new ProductB2(); 
64   } 
65 } 
66 
67 //测试类 
68 public class Client { 
69   public static void main(String[] args) { 
70     //厂商1负责生产产品A1、B1 
71     Factory1 factory1 = new ConcreteFactory1(); 
72     IProductA productA1 = factory1.getProductA1(); 
73     IProductB productB1 = factory1.getProductB1(); 
74      
75     productA1.method(); 
76     productB1.method(); 
77      
78     //厂商2负责生产产品A2、B2 
79     Factory2 factory2 = new ConcreteFactoryB(); 
80     IProductA productA2 = factory2.getProductA2(); 
81     IProductB productB2 = factory2.getProductB2(); 
82      
83     productA2.method(); 
84     productB2.method(); 
85   } 
86 }

三.抽象工厂模式的优缺点

优点

● 分离接口和实现
  客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。

● 使切换产品族变得容易
  因为一个具体的工厂实现代表的是一个产品族,比如上面例子的从Intel系列到AMD系列只需要切换一下具体工厂。

缺点

● 不太容易扩展新的产品
  如果需要给整个产品族添加一个新的产品,那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。

四.应用场景

(1) 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。

(2) 这个系统有多于一个的产品族,而系统只消费其中某一产品族。

(3) 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。

(4) 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

五.工厂方法模式和抽象工厂模式的比较

  抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。而工厂方法模式针对的是一个产品的等级结构。

  工厂方法:一抽象产品类派生出多个具体产品类;一抽象工厂类派生出多个具体工厂类;每个具体工厂类只能创建一个具体产品类的实例。即定义一个创建对象的接口(即抽象工厂类),让其子类(具体工厂类)决定实例化哪一个类(具体产品类)。“一对一”的关系。

  抽象工厂:多个抽象产品类,派生出多个具体产品类;一个抽象工厂类,派生出多个具体工厂类;每个具体工厂类可创建多个具体产品类的实例。即提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体的类。“一对多”的关系。

参考:《Head First设计模式》

http://www.cnblogs.com/forlina/archive/2011/06/21/2086114.html

http://www.cnblogs.com/devinzhang/archive/2011/12/19/2293160.html

原文地址:https://www.cnblogs.com/Eason-S/p/5682480.html