Java 8+工厂模式重构的核心是用Lambda表达式替代if-else/swtich,通过Supplier/Function+Map实现创建逻辑解耦、可配置与热插拔;支持构造方法引用、带参初始化、动态注册及配置中心集成,避免闭包捕获陷阱。

直接用 Lambda 表达式替换传统工厂类里的 if-else 或 switch 分支,把“创建什么对象”变成可配置、可热插拔的行为,是 Java 8+ 工厂模式重构的核心思路。关键不是写得更短,而是让创建逻辑脱离硬编码,支持运行时扩展和外部配置。
用 Supplier + Map 替代静态工厂方法
传统工厂往往靠一堆条件判断返回不同实例,耦合重、难测试、新增类型要改代码。Lambda 重构的第一步,是把构造逻辑抽象成 Supplier
- Map 初始化放在 static 块或配置加载处,支持从 properties/yaml 文件读取后动态注册
- 每个 Supplier 可以是构造方法引用(
MySQLConnection::new),也可以是带初始化逻辑的 Lambda(() -> new PostgreSQLConnection("prod")) - 调用方只需传入字符串 key,无需 import 具体实现类,彻底解耦
支持带参构造与运行时配置
纯 Supplier 不够用?比如数据库连接需要 URL、用户名等参数。这时不要硬塞进构造方法,而是升级为 Function 或自定义函数接口:
- 定义接口:
interface ConnectionBuilder { DatabaseConnection build(Map<string object> config); }</string> - Map 中存配置项(如
"url" → "jdbc:mysql://..."),Lambda 内部解析并构造对象 - 配置可来自 Spring Environment、Consul、或前端表单提交,实现真正动态化
避免硬编码,让类型注册可插拔
把所有 map.put("xxx", Xxx::new) 写死在 static 块里,只是换汤不换药。要实现动态配置,就得把注册过程外移:
- 提供公共注册方法:
public static void register(String type, ConnectionBuilder builder) - 配合 ServiceLoader 或 Spring @Component,让各模块自行注册自己的 builder 实现
- 甚至监听配置中心变更事件,自动 reload 某些类型的 builder,做到零重启扩类型
注意 Lambda 捕获变量的生命周期
如果 Lambda 里引用了外部局部变量(比如 String env = "dev"; () -> new MySQLConnection(env)),Java 要求该变量是 effectively final。这在配置驱动场景中容易踩坑:
- 不要在循环里反复注册同一个 Lambda 并修改捕获变量,会导致所有注册项行为一致
- 推荐把配置封装成不可变对象(如 ConfigDTO),再由 Lambda 引用,安全又清晰
- 若需运行时更新配置,改用 Function 接口 + 显式传参,而非依赖闭包捕获

















