顾名思义,一个可以生产很多“类”的类(工厂)。
工厂模式几乎是所有面向对象开发中都会用到的一种设计模式,譬如Spring框架基于IoC(控制反转)容器的框架,大量依赖于工厂模式来管理对象的创建和生命周期。
工厂模式家族包含以下一些模式。
静态工厂模式(Static Factory Pattern)
一种简化版的工厂模式,通过包含静态方法的类来创建对象,客户端通过调用该静态方法并传入参数来获取所需的实例。
[] 静态工厂模式不是GoF的23中设计模式之一,但属于一种常见的编成实践。其核心是:
- 提供一个静态工厂方法(static factory method)
- 方法根据参数或逻辑返回不同的实现类实例
- 客户端不需要使用
new
关键字直接创建对象
由于静态工厂模式不符合开闭原则,因此不能被继承,无法实现多态。往往只能用于创建单一固定类型的类
,或者说是final
的类,下面是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class SocketFactory { public static ServerSocket createServerSocket() { return new ServerSocket(); } public static Socket createSocket() { return new Socket(); } public static Socket createSocket(boolean keepAlive) { Socket socket = new Socket(); socket.setKeepAlive(keepAlive); return socket; } ... }
|
基于它的定义,静态工厂更多的用作辅助类来使用,Java标准库中广泛使用了静态工厂方法,有:
java.util.Collections#unmodifiableList(List<T> list)
java.util.Arrays#asList(T... a)
java.util.Optional#of(T value)
java.time.LocalDate#now()
java.nio.file.Paths.get(...)
静态工厂适用于框架内部本身希望统一对象的构建过程,同时不希望在外部进行扩展的类。
简单工厂模式(Simple Factory Pattern)
通过一个工厂类统一创建不同类型的对象,客户端无需指导具体类名,只需传入参数即可。
简单工厂也是违反了“开闭原则”,新增的产品类需要修改工厂类。
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
| public interface Product { void use(); }
public class ProductA implements Product { public void use() { System.out.println("Using Product A"); } }
public class ProductB implements Product { public void use() { System.out.println("Using Product B"); } }
public class SimpleFactory {
public Product createProduct(String type) { return switch(type) { case "A" -> new ProductA(); case "B" -> new ProductB(); default -> throw new UnsupportedOperation("Unsupported Product Type"); } } }
|
违反“开闭原则”,每次新增产品时,都需要修改工厂类。
工厂方法模式(Factory Method Pattern)
每个工厂只生产一种产品,新增产品只需扩展不需要修改,符合开闭原则。
定义一个创建对象的接口,但由子类决定要实例化哪个类。工厂方法模式把类的实例化过程推迟到子类。
对比UML可以发现,工厂方法就是在原来的简单工厂模式的前提下,将原来的SimpleFactory
提升为interface
或abstract
,延迟到具体的工厂类进行构建。这种实现满足了“开闭原则”。
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
| public interface Product { void use(); }
public class ProductA implements Product { public void use() { System.out.println("Using Product A"); } } public class ProductB implements Product { public void use() { System.out.println("Using Product B"); } }
public interface Factory { Product createProduct(); }
public class FactoryA implement Factory { public Product createProduct() { return new ProductA(); } }
public class FactoryB implement Factory { public Product createProduct() { return new ProductB(); } }
|
工厂方法,由子类来决定类的实例化。
抽象工厂(Abstract Factory Pattern)
提供一个接口,用于创建一组相关的或依赖对象的家族,适用于多平台、多配置系统(如跨平台UI控件库)。
抽象工厂模式在基于原来的工厂方法模式的前提下,由单一类型,扩展为可以创建多种产品类型。
具体实现类,
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 46 47 48 49 50
| public interface ProductA { void featureA(); } public class ProductA1 implement ProductA { public void featureA() { System.out.println("Feature of Product A1"); } } public class ProductA2 implement ProductA { public void featureA() { System.out.println("Feature of Product A2"); } } public interface ProductB { void featureB(); } public class ProductB1 implement ProductB { public void featureB() { System.out.println("Feature of Product B1"); } } public class ProductB2 implement ProductB { public void featureB() { System.out.println("Feature of Product B2"); } }
public interface AbstractFactory { ProductA createProductA(); ProductB createProductB(); }
public class Factory1 implements AbstractFactory { public ProductA createProductA() { return new ProductA1(); } public ProductB createProductB() { return new ProductB1(); } }
public class Factory2 implements AbstractFactory { public ProductA createProductA() { return new ProductA2(); } public ProductB createProductB() { return new ProductB2(); } }
|
抽象工厂,由单一类型,扩展为支持多种类型。
总结
模式名称 |
创建对象数量 |
是否符合开闭原则 |
使用场景 |
简单工厂模式 |
单一类型 |
否 |
简单对象创建,不频繁变更 |
工厂方法模式 |
单一类型 |
是 |
需要灵活扩展产品类型 |
抽象工厂模式 |
多种类型 |
是 |
创建多个相关或依赖对象的家族 |