在软件开发中,对象创建是最基础也是最关键的环节之一。随着系统复杂度增加,直接使用new
关键字创建对象会导致:
工厂模式正是为解决这类问题而生的设计模式。它通过将对象创建过程封装,实现了:
本文将深入剖析三种工厂模式(简单工厂、工厂方法、抽象工厂)的原理、实现及最佳实践。
模式类型 | 解决的核心问题 | 适用场景 | 复杂度 |
---|---|---|---|
简单工厂 | 统一创建接口 | 对象种类有限且固定 | ★☆☆ |
工厂方法 | 单一产品族扩展 | 需要动态扩展产品类型 | ★★☆ |
抽象工厂 | 多产品族扩展 | 需要创建相关产品家族 | ★★★ |
定义一个工厂类,根据传入参数的不同返回不同类的实例,被创建的实例通常具有共同的父类或接口。
classDiagram
class Client
class SimpleFactory {
+createProduct(String type) Product
}
interface Product {
<>
+operation()
}
class ConcreteProductA {
+operation()
}
class ConcreteProductB {
+operation()
}
Client --> SimpleFactory
Client --> Product
SimpleFactory ..> ConcreteProductA : 创建
SimpleFactory ..> ConcreteProductB : 创建
Product <|.. ConcreteProductA
Product <|.. ConcreteProductB
// 产品接口
public interface Shape {
void draw();
}
// 具体产品
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("绘制圆形");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("绘制矩形");
}
}
// 简单工厂
public class ShapeFactory {
public Shape createShape(String type) {
if ("circle".equalsIgnoreCase(type)) {
return new Circle();
} else if ("rectangle".equalsIgnoreCase(type)) {
return new Rectangle();
}
throw new IllegalArgumentException("未知图形类型: " + type);
}
}
// 客户端
public class Client {
public static void main(String[] args) {
ShapeFactory factory = new ShapeFactory();
Shape circle = factory.createShape("circle");
circle.draw(); // 输出: 绘制圆形
Shape rectangle = factory.createShape("rectangle");
rectangle.draw(); // 输出: 绘制矩形
}
}
优点:
缺点:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
classDiagram
class Client
interface Factory {
<>
+createProduct() Product
}
class ConcreteFactoryA {
+createProduct() Product
}
class ConcreteFactoryB {
+createProduct() Product
}
interface Product {
<>
+operation()
}
class ConcreteProductA {
+operation()
}
class ConcreteProductB {
+operation()
}
Client --> Factory
Client --> Product
Factory <|.. ConcreteFactoryA
Factory <|.. ConcreteFactoryB
Product <|.. ConcreteProductA
Product <|.. ConcreteProductB
ConcreteFactoryA ..> ConcreteProductA : 创建
ConcreteFactoryB ..> ConcreteProductB : 创建
// 数据库连接产品
public interface Connection {
void connect();
void executeQuery(String sql);
}
// MySQL连接
public class MySQLConnection implements Connection {
@Override
public void connect() {
System.out.println("MySQL连接已建立");
}
@Override
public void executeQuery(String sql) {
System.out.println("执行MySQL查询: " + sql);
}
}
// PostgreSQL连接
public class PostgreSQLConnection implements Connection {
@Override
public void connect() {
System.out.println("PostgreSQL连接已建立");
}
@Override
public void executeQuery(String sql) {
System.out.println("执行PostgreSQL查询: " + sql);
}
}
// 工厂接口
public interface ConnectionFactory {
Connection createConnection();
}
// MySQL工厂
public class MySQLFactory implements ConnectionFactory {
@Override
public Connection createConnection() {
return new MySQLConnection();
}
}
// PostgreSQL工厂
public class PostgreSQLFactory implements ConnectionFactory {
@Override
public Connection createConnection() {
return new PostgreSQLConnection();
}
}
// 客户端
public class DatabaseClient {
public void executeQuery(ConnectionFactory factory, String sql) {
Connection conn = factory.createConnection();
conn.connect();
conn.executeQuery(sql);
}
public static void main(String[] args) {
DatabaseClient client = new DatabaseClient();
// 使用MySQL
client.executeQuery(new MySQLFactory(), "SELECT * FROM users");
// 使用PostgreSQL
client.executeQuery(new PostgreSQLFactory(), "SELECT * FROM orders");
}
}
public interface ConnectionFactory {
Connection createConnection(String config);
}
public class DynamicDBFactory implements ConnectionFactory {
@Override
public Connection createConnection(String dbType) {
switch (dbType.toLowerCase()) {
case "mysql": return new MySQLConnection();
case "postgresql": return new PostgreSQLConnection();
default: throw new IllegalArgumentException("未知数据库类型");
}
}
}
public abstract class AbstractConnectionFactory implements ConnectionFactory {
// 默认实现
@Override
public Connection createConnection() {
return createConnection("default");
}
// 抽象方法
public abstract Connection createConnection(String config);
}
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
classDiagram
class Client
interface AbstractFactory {
<>
+createButton() Button
+createCheckbox() Checkbox
}
class WinFactory {
+createButton() Button
+createCheckbox() Checkbox
}
class MacFactory {
+createButton() Button
+createCheckbox() Checkbox
}
interface Button {
<>
+render()
}
interface Checkbox {
<>
+render()
}
class WinButton {
+render()
}
class WinCheckbox {
+render()
}
class MacButton {
+render()
}
class MacCheckbox {
+render()
}
Client --> AbstractFactory
AbstractFactory <|.. WinFactory
AbstractFactory <|.. MacFactory
Button <|.. WinButton
Button <|.. MacButton
Checkbox <|.. WinCheckbox
Checkbox <|.. MacCheckbox
WinFactory ..> WinButton
WinFactory ..> WinCheckbox
MacFactory ..> MacButton
MacFactory ..> MacCheckbox
// 抽象产品:按钮
public interface Button {
void render();
void onClick();
}
// 抽象产品:复选框
public interface Checkbox {
void render();
void onCheck();
}
// Windows按钮
public class WinButton implements Button {
@Override
public void render() {
System.out.println("渲染Windows风格按钮");
}
@Override
public void onClick() {
System.out.println("Windows按钮点击事件处理");
}
}
// Windows复选框
public class WinCheckbox implements Checkbox {
@Override
public void render() {
System.out.println("渲染Windows风格复选框");
}
@Override
public void onCheck() {
System.out.println("Windows复选框选中事件处理");
}
}
// Mac按钮
public class MacButton implements Button {
@Override
public void render() {
System.out.println("渲染macOS风格按钮");
}
@Override
public void onClick() {
System.out.println("macOS按钮点击事件处理");
}
}
// Mac复选框
public class MacCheckbox implements Checkbox {
@Override
public void render() {
System.out.println("渲染macOS风格复选框");
}
@Override
public void onCheck() {
System.out.println("macOS复选框选中事件处理");
}
}
// 抽象工厂
public interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// Windows工厂
public class WinFactory implements GUIFactory {
@Override
public Button createButton() {
return new WinButton();
}
@Override
public Checkbox createCheckbox() {
return new WinCheckbox();
}
}
// Mac工厂
public class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
// 客户端
public class Application {
private final Button button;
private final Checkbox checkbox;
public Application(GUIFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}
public void renderUI() {
button.render();
checkbox.render();
}
public void simulateUserActions() {
button.onClick();
checkbox.onCheck();
}
public static void main(String[] args) {
// 根据配置决定使用哪个工厂
GUIFactory factory;
if (System.getProperty("os.name").toLowerCase().contains("win")) {
factory = new WinFactory();
} else {
factory = new MacFactory();
}
Application app = new Application(factory);
app.renderUI();
app.simulateUserActions();
}
}
// 新增Material Design主题
public class MaterialButton implements Button {
// 实现略...
}
public class MaterialCheckbox implements Checkbox {
// 实现略...
}
public class MaterialFactory implements GUIFactory {
@Override
public Button createButton() {
return new MaterialButton();
}
@Override
public Checkbox createCheckbox() {
return new MaterialCheckbox();
}
}
// 动态切换主题
public class ThemeManager {
private static GUIFactory currentFactory = new WinFactory();
public static void setTheme(String theme) {
switch (theme.toLowerCase()) {
case "windows": currentFactory = new WinFactory(); break;
case "mac": currentFactory = new MacFactory(); break;
case "material": currentFactory = new MaterialFactory(); break;
default: throw new IllegalArgumentException("未知主题");
}
}
public static GUIFactory getFactory() {
return currentFactory;
}
}
对象池技术
public class ConnectionPoolFactory implements ConnectionFactory {
private static final int POOL_SIZE = 10;
private final Queue<Connection> pool = new LinkedList<>();
public ConnectionPoolFactory() {
for (int i = 0; i < POOL_SIZE; i++) {
pool.add(new MySQLConnection());
}
}
@Override
public Connection createConnection() {
if (pool.isEmpty()) {
return new MySQLConnection();
}
return pool.poll();
}
public void releaseConnection(Connection conn) {
if (pool.size() < POOL_SIZE) {
pool.offer(conn);
}
}
}
缓存重用
public class ShapeFactory {
private static final Map<String, Shape> cache = new HashMap<>();
public Shape getShape(String type) {
return cache.computeIfAbsent(type, t -> {
switch (t.toLowerCase()) {
case "circle": return new Circle();
case "rectangle": return new Rectangle();
default: throw new IllegalArgumentException();
}
});
}
}
// 使用Spring框架的依赖注入
@Configuration
public class FactoryConfig {
@Bean
@ConditionalOnProperty(name = "db.type", havingValue = "mysql")
public ConnectionFactory mysqlFactory() {
return new MySQLFactory();
}
@Bean
@ConditionalOnProperty(name = "db.type", havingValue = "postgresql")
public ConnectionFactory postgresFactory() {
return new PostgreSQLFactory();
}
}
// 客户端直接注入
@Service
public class DatabaseService {
private final ConnectionFactory factory;
@Autowired
public DatabaseService(ConnectionFactory factory) {
this.factory = factory;
}
public void executeQuery(String sql) {
Connection conn = factory.createConnection();
conn.executeQuery(sql);
}
}
// Collections工厂方法
List<String> list = List.of("Java", "Python", "Go");
Set<Integer> set = Set.of(1, 2, 3);
Map<String, Integer> map = Map.of("A", 1, "B", 2);
// 内部实现(简化)
public interface List<E> {
static <E> List<E> of(E... elements) {
return new ImmutableCollections.ListN<>(elements);
}
}
// BeanFactory是顶级工厂接口
public interface BeanFactory {
Object getBean(String name) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
}
// 应用场景
@Service
public class OrderService {
@Autowired // 依赖注入相当于工厂
private PaymentFactory paymentFactory;
public void processOrder(Order order) {
Payment payment = paymentFactory.create(order.getPaymentType());
payment.process(order.getAmount());
}
}
// 日志工厂
Logger logger = LogManager.getLogger(MyClass.class);
// 内部工厂实现(简化)
public final class LogManager {
public static Logger getLogger(Class<?> clazz) {
return getLogger(clazz.getName());
}
public static Logger getLogger(String name) {
return ContextSelector.getContext().getLogger(name);
}
}
过度设计简单对象创建
// 反例:简单对象使用复杂工厂
public class UserFactory {
public User createUser(String name) {
return new User(name); // 直接new就能解决
}
}
工厂类成为上帝对象
// 反例:工厂类承担过多职责
public class SuperFactory {
public ProductA createA() { /* ... */ }
public ProductB createB() { /* ... */ }
public ProductC createC() { /* ... */ }
public void validate() { /* ... */ }
public void save() { /* ... */ } // 违反单一职责
}
遵循单一职责原则
优先使用工厂方法
// 正例:使用工厂方法而非简单工厂
public interface ConnectionFactory {
Connection create();
}
public class MySQLFactory implements ConnectionFactory {
@Override
public Connection create() {
return new MySQLConnection();
}
}
public interface ShapeFactory {
Shape create();
}
// 使用Lambda表达式
ShapeFactory circleFactory = () -> new Circle();
Shape circle = circleFactory.create();
// 方法引用
ShapeFactory rectangleFactory = Rectangle::new;
Shape rectangle = rectangleFactory.create();
module com.example.shapes {
exports com.example.shapes.api;
provides com.example.shapes.api.ShapeFactory
with com.example.shapes.impl.CircleFactory;
}
// 服务加载
ServiceLoader<ShapeFactory> loader =
ServiceLoader.load(ShapeFactory.class);
ShapeFactory factory = loader.findFirst().orElseThrow();
Shape shape = factory.create();
public interface ReactiveFactory<T> {
Mono<T> createAsync();
}
public class DatabaseConnectionFactory implements ReactiveFactory<Connection> {
@Override
public Mono<Connection> createAsync() {
return Mono.fromCallable(() -> {
Connection conn = new MySQLConnection();
conn.connect();
return conn;
}).subscribeOn(Schedulers.boundedElastic());
}
}
工厂模式通过封装对象创建实现了:
设计启示:
不要直接创建对象,让工厂为你服务;不要依赖具体实现,依赖抽象接口
正如《设计模式》作者GoF所强调:
“工厂模式是对象创建的封装艺术,它让系统可以在不修改代码的情况下应对变化”
扩展思考:
- 如何在分布式系统中实现工厂模式?
- 工厂模式如何与领域驱动设计(DDD)结合?
- 无工厂模式 vs 过度使用工厂模式的平衡点在哪里?
模式 | 实现要点 | 应用场景 |
---|---|---|
简单工厂 | 一个工厂类 + 条件判断 | 对象类型有限且固定 |
工厂方法 | 工厂接口 + 多个实现类 | 需要扩展产品类型 |
抽象工厂 | 抽象工厂接口 + 多个产品族 | 需要创建相关产品家族 |
静态工厂 | 工厂类的静态方法 | 工具类对象创建 |
Lambda工厂 | 函数式接口 + Lambda | 简单对象的动态创建 |
工厂模式是构建灵活、可扩展系统的基石,在框架设计、业务解耦等场景中具有不可替代的价值。