友情支持

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

支付宝

微信

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

wx jikerizhi

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

14. 工厂方法模式

14.1. 定义

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

工厂方法模式(Factory Method)

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

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

14.2. 类图

Diagram

简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。

既然这个工厂类与分支耦合,那么我就对它下手,根据依赖倒转原则,我们把工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的工厂方法。然后,所有的要生产具体类的工厂,就去实现这个接口,这样,一个简单工厂模式的工厂类,变成了一个工厂抽象接口和多个具体生成对象的工厂,

工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。你想要加功能,本来是改工厂类的,而现在是修改客户端!

工厂方法克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点。

它们都是集中封装了对象的创建,使得要更换对象时,不需要做大的改动就可实现,降低了客户程序与产品对象的耦合。工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。但缺点是由于每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。

利用‘反射’可以解决避免分支判断的问题。

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

/**
 * ConcreteFactory 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-23 09:09:48
 */
public class ConcreteFactory extends Factory {
  public Product factoryMethod() {
    return new ConcreteProduct();
  }
}
代码 89. factorymethod/ConcreteProduct.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.diguage.didp.factorymethod;

/**
 * ConcreteProduct 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-23 09:09:48
 */
public class ConcreteProduct extends Product {
}
代码 90. factorymethod/Factory.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package com.diguage.didp.factorymethod;

/**
 * Factory 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:34
 */
public abstract class Factory {
  public abstract Product factoryMethod();
}
代码 91. factorymethod/Product.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.diguage.didp.factorymethod;

/**
 * Product 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:34
 */
public abstract class Product {
}
代码 92. factorymethod/Client.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package com.diguage.didp.factorymethod;

/**
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-24
 */
public class Client {
  public static void main(String[] args) {
    Factory factory = new ConcreteFactory();
    Product product = factory.factoryMethod();
    System.out.println(product.getClass().getName());
  }
}