友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

5. 抽象工厂模式

5.1. 定义

根据 GoF 的著名著作 《设计模式》,抽象工厂模式的定义如下:

抽象工厂模式(Abstract Factory)

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

— Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides
《设计模式》

5.2. 类图

Diagram

菜鸟程序员碰到问题,只会用时间来摆平

工厂方法模式是定义一个用于创建对象的接口,让子类决定实例化哪一个类。

AbstractProductA和AbstractProductB是两个抽象产品,之所以为抽象,是因为它们都有可能有两种不同的实现,就刚才的例子来说就是User和Department,而ProductA1、ProductA2和ProductB1、ProductB2就是对两个抽象产品的具体分类的实现

IFactory是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。而ConcreteFactory1和ConcreteFactory2就是具体的工厂了。

通常是在运行时刻再创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端应使用不同的具体工厂。

最大的好处便是易于交换产品系列,由于具体工厂类

在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。

我们的设计不能去防止需求的更改,那么我们的理想便是让改动变得最小

第二大好处是,它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。

是个模式都是会有缺点的,都有不适用的时候,要辨证地看待问题哦。

编程是门艺术,这样大批量的改动,显然是非常丑陋的做法。

客户端没有出现任何一个SQL Server或Access的字样,达到了解耦的目的。

依赖注入(Dependency Injection)

从这个角度上说,所有在用简单工厂的地方,都可以考虑用反射技术来去除switch或if,解除分支判断带来的耦合。

一个程序员如果从来没有熬夜写程序的经历,不能算是一个好程序员,因为他没有痴迷过,所以他不会有大成就。

无痴迷,不成功。

代码 37. abstractfactory/AbstractFactory.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package com.diguage.didp.abstractfactory;

/**
 * AbstractFactory 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public abstract class AbstractFactory {
  public abstract AbstractProductA createProductA();

  public abstract AbstractProductB createProductB();
}
代码 38. abstractfactory/AbstractProductA.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.diguage.didp.abstractfactory;

/**
 * AbstractProductA 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public abstract class AbstractProductA {
}
代码 39. abstractfactory/AbstractProductB.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.diguage.didp.abstractfactory;

/**
 * AbstractProductB 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public abstract class AbstractProductB {
}
代码 40. abstractfactory/Client.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.diguage.didp.abstractfactory;

/**
 * Client 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class Client {
  private AbstractFactory factory;
  private AbstractProductA productA;
  private AbstractProductB productB;

  private String type;

  public Client(String type) {
    this.type = type;
    if ("A".equals(this.type) || "a".equals(this.type)) {
      factory = new ConcreteFactory1();
    } else {
      factory = new ConcreteFactory2();
    }
    productA = factory.createProductA();
    productB = factory.createProductB();
  }

  public AbstractFactory getFactory() {
    return factory;
  }

  public AbstractProductA getProductA() {
    return productA;
  }

  public AbstractProductB getProductB() {
    return productB;
  }

  public static void main(String[] args) {
    Client client = new Client("a");
    System.out.println(client.getFactory().getClass());
    System.out.println(client.getProductA().getClass());
    System.out.println(client.getProductB().getClass());
  }
}
代码 41. abstractfactory/ConcreteFactory1.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package com.diguage.didp.abstractfactory;

/**
 * ConcreteFactory1 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class ConcreteFactory1 extends AbstractFactory {
  public AbstractProductA createProductA() {
    return new ProductA1();
  }

  public AbstractProductB createProductB() {
    return new ProductB1();
  }
}
代码 42. abstractfactory/ConcreteFactory2.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package com.diguage.didp.abstractfactory;

/**
 * ConcreteFactory2 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class ConcreteFactory2 extends AbstractFactory {
  public AbstractProductA createProductA() {
    return new ProductA2();
  }

  public AbstractProductB createProductB() {
    return new ProductB2();
  }
}
代码 43. abstractfactory/ProductA1.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.diguage.didp.abstractfactory;

/**
 * ProductA1 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class ProductA1 extends AbstractProductA {
}
代码 44. abstractfactory/ProductA2.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.diguage.didp.abstractfactory;

/**
 * ProductA2 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class ProductA2 extends AbstractProductA {
}
代码 45. abstractfactory/ProductB1.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.diguage.didp.abstractfactory;

/**
 * ProductB1 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class ProductB1 extends AbstractProductB {
}
代码 46. abstractfactory/ProductB2.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.diguage.didp.abstractfactory;

/**
 * ProductB2 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class ProductB2 extends AbstractProductB {
}

5.3. 常见示例

  1. java.util.Calendar.getInstance()

  2. java.util.ResourceBundle.getBundle(*)

  3. java.sql.DriverManager.getConnection(*)

  4. java.sql.Connection.createStatement(*)

  5. java.sql.Statement.executeQuery(String sql)

  6. java.text.NumberFormat.getInstance(*)

  7. javax.xml.transform.TransformerFactory.newInstance(*)