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) 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
五.工厂方法模式和抽象工厂模式的比较
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。而工厂方法模式针对的是一个产品的等级结构。
工厂方法:一抽象产品类派生出多个具体产品类;一抽象工厂类派生出多个具体工厂类;每个具体工厂类只能创建一个具体产品类的实例。即定义一个创建对象的接口(即抽象工厂类),让其子类(具体工厂类)决定实例化哪一个类(具体产品类)。“一对一”的关系。
抽象工厂:多个抽象产品类,派生出多个具体产品类;一个抽象工厂类,派生出多个具体工厂类;每个具体工厂类可创建多个具体产品类的实例。即提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体的类。“一对多”的关系。