当前位置: 首页 > article >正文

Java工厂方法模式详解

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它将对象的创建和使用分离,通过定义一个创建对象的接口,让子类决定实例化哪个类。这种模式提高了代码的可扩展性和可维护性,尤其适用于需要根据不同条件创建不同类型对象的场景。

核心概念

  • 产品(Product):定义产品的接口或抽象类。
  • 具体产品(ConcreteProduct):实现产品接口的具体类。
  • 工厂(Creator):声明创建产品的抽象方法(工厂方法)。
  • 具体工厂(ConcreteCreator):实现工厂方法,返回具体产品的实例。

简单工厂模式(静态工厂)

在介绍工厂方法模式前,先看一个简单工厂的实现:

// 产品接口
interface Product {void operation();
}// 具体产品
class ConcreteProductA implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductA operation");}
}class ConcreteProductB implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductB operation");}
}// 简单工厂类
class SimpleFactory {public static Product createProduct(String type) {switch (type) {case "A":return new ConcreteProductA();case "B":return new ConcreteProductB();default:throw new IllegalArgumentException("Unsupported product type");}}
}// 使用示例
public class Client {public static void main(String[] args) {Product productA = SimpleFactory.createProduct("A");productA.operation(); // 输出: ConcreteProductA operation}
}

缺点:简单工厂违反了开闭原则(对扩展开放,对修改关闭)。新增产品时需要修改工厂类的逻辑。

工厂方法模式(标准实现)

工厂方法模式将创建逻辑延迟到子类,避免修改基类:

// 产品接口
interface Product {void operation();
}// 具体产品
class ConcreteProductA implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductA operation");}
}class ConcreteProductB implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductB operation");}
}// 抽象工厂
abstract class Creator {// 工厂方法public abstract Product factoryMethod();// 业务逻辑public void someOperation() {Product product = factoryMethod();product.operation();}
}// 具体工厂A
class ConcreteCreatorA extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductA();}
}// 具体工厂B
class ConcreteCreatorB extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductB();}
}// 使用示例
public class Client {public static void main(String[] args) {Creator creatorA = new ConcreteCreatorA();creatorA.someOperation(); // 输出: ConcreteProductA operationCreator creatorB = new ConcreteCreatorB();creatorB.someOperation(); // 输出: ConcreteProductB operation}
}

工厂方法模式的变体

1. 参数化工厂方法

通过参数指定创建的产品类型,将选择逻辑移至工厂类:

abstract class Creator {public Product createProduct(String type) {Product product = factoryMethod(type);// 其他初始化逻辑return product;}protected abstract Product factoryMethod(String type);
}class ConcreteCreator extends Creator {@Overrideprotected Product factoryMethod(String type) {switch (type) {case "A":return new ConcreteProductA();case "B":return new ConcreteProductB();default:throw new IllegalArgumentException("Unsupported type");}}
}
2. 使用反射的工厂

通过类名或 Class 对象动态创建产品,避免大量的条件判断:

class ReflectiveCreator {public <T extends Product> T createProduct(Class<T> clazz) {try {return clazz.getDeclaredConstructor().newInstance();} catch (Exception e) {throw new RuntimeException("Product creation failed", e);}}
}// 使用示例
ReflectiveCreator creator = new ReflectiveCreator();
Product productA = creator.createProduct(ConcreteProductA.class);

工厂方法模式的应用场景

  1. 对象创建逻辑复杂:例如数据库连接对象,需要配置参数、初始化资源等。
  2. 根据条件动态创建对象:例如游戏中根据关卡生成不同的敌人。
  3. 框架设计:例如 Java 的Calendar.getInstance()方法。
  4. 解耦对象创建与使用:提高代码可维护性,例如 Spring 框架的BeanFactory

优缺点

优点

  • 符合开闭原则:新增产品只需添加新的具体工厂类,无需修改基类。
  • 降低耦合度:将对象创建逻辑封装在工厂类中。
  • 提高代码可扩展性:便于引入新产品。

缺点

  • 类数量增加:每个具体产品都需要对应的具体工厂类。
  • 代码复杂度上升:简单场景可能过度设计。

与其他模式的对比

  1. 简单工厂 vs 工厂方法

    • 简单工厂:通过静态方法创建对象,不支持开闭原则。
    • 工厂方法:通过继承和多态实现对象创建,支持开闭原则。
  2. 工厂方法 vs 抽象工厂

    • 工厂方法:专注于创建单一产品。
    • 抽象工厂:创建一组相关产品(产品族),强调产品之间的依赖关系。

总结

工厂方法模式是创建型设计模式中最常用的模式之一,它通过将对象创建逻辑延迟到子类,实现了代码的可扩展性和可维护性。在实际开发中,根据场景选择合适的变体(如参数化工厂、反射工厂)可以进一步简化代码。

http://www.lryc.cn/news/2394816.html

相关文章:

  • 【pytorch学习】土堆pytorch学习笔记2
  • Eclipse 插件开发 5.3 编辑器 监听输入
  • iOS 集成网易云信IM
  • Parasoft C++Test软件单元测试_实例讲解(对多次调用的函数打桩)
  • azure web app创建分步指南系列之二
  • 题海拾贝:P8598 [蓝桥杯 2013 省 AB] 错误票据
  • MySQL 8.0:解析
  • Python量化交易12——Tushare全面获取各种经济金融数据
  • 封装一个小程序选择器(可多选、单选、搜索)
  • Dest建筑能耗模拟仿真功能简介
  • 【Hot 100】121. 买卖股票的最佳时机
  • 【机器学习基础】机器学习入门核心算法:XGBoost 和 LightGBM
  • Linux | Shell脚本的常用命令
  • 跑步的强度等级分类
  • 【JUC】深入解析 JUC 并发编程:单例模式、懒汉模式、饿汉模式、及懒汉模式线程安全问题解析和使用 volatile 解决内存可见性问题与指令重排序问题
  • 2025年全国青少年信息素养大赛复赛C++算法创意实践挑战赛真题模拟强化训练(试卷3:共计6题带解析)
  • Mongodb | 基于Springboot开发综合社交网络应用的项目案例(中英)
  • 飞腾D2000与FPGA结合的主板
  • 百度量子蜘蛛3.0横空出世,搜索引擎迎来“量子跃迁“级革命
  • GitHub开源|AI顶会论文中文翻译PDF合集(gpt-translated-pdf-zh)
  • JSR 303(即 Bean Validation)是一个通过​​注解在 Java Bean 上定义和执行验证规则​​的规范
  • 5G 网络中的双向认证机制解析
  • DAY07:Vue Router深度解析与多页面博客系统实战
  • Drawio编辑器二次开发
  • 1.测试过程之需求分析和测试计划
  • 第三十七天打卡
  • Qt 窗口标志(Window Flags)详解:控制窗口样式与行为
  • ABP VNext + CRDT 打造实时协同编辑
  • 微信小程序真机调试时如何实现与本地开发环境服务器交互
  • Linux: network: dpdk, VF, ip link set down 对VF不生效