友情支持
如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜
有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。
公众号的微信号是: jikerizhi 。因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。 |
14. 工厂方法模式
14.1. 定义
根据 GoF 的著名著作 《设计模式》,工厂方法模式的定义如下:
- 工厂方法模式(Factory Method)
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
— Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides
《设计模式》
《设计模式》
14.2. 类图
简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
既然这个工厂类与分支耦合,那么我就对它下手,根据依赖倒转原则,我们把工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的工厂方法。然后,所有的要生产具体类的工厂,就去实现这个接口,这样,一个简单工厂模式的工厂类,变成了一个工厂抽象接口和多个具体生成对象的工厂,
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。你想要加功能,本来是改工厂类的,而现在是修改客户端!
工厂方法克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点。
它们都是集中封装了对象的创建,使得要更换对象时,不需要做大的改动就可实现,降低了客户程序与产品对象的耦合。工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。但缺点是由于每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。
利用‘反射’可以解决避免分支判断的问题。
代码 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());
}
}