Table of Contents

一、定义

在创建一个对象时不向客户暴露内部细节,并提供一个创建对象的通用接口。

二、简单工厂的用法

简单工厂的本质在于选择,而非实现。 所以实现简单工厂的难点就在于如何选择,我们可以采用参数传递、配置文件等等方式来尝试实现。

何时选用简单工厂

  • 如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选择简单工厂。
  • 如果想要把对外创建对象的职责集中管理和控制,可以选择简单工厂

简单工厂模式优缺点

  1. 优点
    • 将创建实例与使用实例的任务分开,使用者不必关心对象是如何创建的,实现了系统的解耦。
    • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可。
  2. 缺点
    • 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
    • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,也有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

应用场景

  • 工厂类负责创建的对象比较少:由于创建的对象比较少,不会造成工厂方法中业务逻辑过于复杂。
  • 客户端只需知道传入工厂类静态方法的参数,而不需要关心创建对象的细节。

三、实现

1. Class Diagram

摘自CSNote

简单工厂把实例化的操作单独放到一个类中,这个类就成为简单工厂类,让简单工厂类来决定应该用哪个具体子类来实例化。

这样做能把客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。客户类往往有多个,如果不使用简单工厂,那么所有的客户类都要知道所有子类的细节。而且一旦子类发生改变,例如增加子类,那么所有的客户类都要进行修改。

img

2. Implementation

1
2
public interface Product {
}
1
2
public class ConcreteProduct implements Product {
}
1
2
public class ConcreteProduct1 implements Product {
}
1
2
public class ConcreteProduct2 implements Product {
}

以下的 Client 类包含了实例化的代码,这是一种错误的实现。如果在客户类中存在这种实例化代码,就需要考虑将代码放到简单工厂中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class Client {

    public static void main(String[] args) {
        int type = 1;
        Product product;
        if (type == 1) {
            product = new ConcreteProduct1();
        } else if (type == 2) {
            product = new ConcreteProduct2();
        } else {
            product = new ConcreteProduct();
        }
        // do something with the product
    }
}

以下的 SimpleFactory 是简单工厂实现,它被所有需要进行实例化的客户类调用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class SimpleFactory {
    
    public Product createProduct(int type) {
        if (type == 1) {
            return new ConcreteProduct1();
        } else if (type == 2) {
            return new ConcreteProduct2();
        }
        return new ConcreteProduct();
    }
}
1
2
3
4
5
6
7
8
public class Client {

    public static void main(String[] args) {
        SimpleFactory simpleFactory = new SimpleFactory();
        Product product = simpleFactory.createProduct(1);
        // do something with the product
    }
}

简单工厂模式参考