*说明:本文参考书籍《设计模式之禅》第2版,作者:秦小波,章节:第8章。
1.定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
工厂方法使一个类的实例化延迟到其子类。
2.通用类图

*说明:
- 抽象产品类Product负责定义产品的共性,实现对事物的最抽象的定义。
- 抽象工厂类Creator,具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的。
3.通用代码
3.1抽象产品类
- public abstract class Product {
-
- public void method1(){
-
- }
-
- public abstract void method2();
- }
3.2具体产品类
具体的产品类可以有多个,都继承了抽象产品类。
-
- public class ConcreteProduct1 extends Product {
- public void method2(){
- <span style="white-space:pre"> </span>
- }
- }
-
-
- public class ConcreteProduct1 extends Product {
- public void method2(){
-
- }
- }
3.3抽象工厂类
抽象工厂类负责定义产品对象的产生。
- public abstract class Creator {
-
- public abstract <T extends Product> T createProduct(Class<T> c);
- }
3.4具体工厂类
具体的工厂产生具体的产品。
- public class ConcreteCreator extends Creator {
- public abstract <T extends Product> T createProduct(Class<T> c){
- Product product = null;
- try {
- product = (Product)Class.forName(c.getName()).newInstance();
- } catch (Exception e) {
-
- }
- return (T)product;
- }
- }
3.5场景类
- public class Client {
- public static void main(String[] args){
-
- Creator creator = new ConcreteCreator();
-
-
-
-
- Product product1 = creator.createProduct(ConcreteCreator1.class);
-
-
-
-
-
- Product product2 = creator.createProduct(ConcreteCreator2.class);
-
- }
- }
4.优缺点
4.1优点
- 良好的封装性,代码结构清晰,降低了模块间的耦合
- 优秀的扩展性
- 屏蔽了产品类,调用者只关心产品的接口
- 工厂方法模式是典型的解耦框架
4.2缺点
- 每增加一个产品,相应的也要增加一个子工厂,导致系统中类的个数增加,在一定程度上增加了系统的复杂度。
5.使用举例
设计一个连接邮件服务器的框架时,有3种网络协议可供选择:POP3、IMAP、HTTP,我们可以把这三种连接方法作为产品类,定义一个接口如IConnectMail,然后定义对邮件的操作方法,用不同的方法实现三个具体的产品类(也就是连接方式);再定义一个工厂方法,按照不同的传入条件,选择不同的连接方式。如此设计,可以做到完美扩展。