java中用intfunction配合枚举实现工厂模式,核心在于利用枚举的单例性与类型安全,再通过函数式接口提升泛型创建能力与执行效率。

Java中用IntFunction配合枚举实现工厂模式,核心在于**利用枚举的单例性与类型安全,再通过函数式接口提升泛型创建能力与执行效率**。它不是简单替代传统switch,而是让“类型→行为”的映射更紧凑、更可扩展,且避免反射开销。
为什么选IntFunction而不是普通工厂方法?
IntFunction<t></t>代表“输入int,输出T”的函数接口,天然适配以整型编码(如数据库字段、协议码、配置项)驱动的工厂场景。相比传统if-else或switch,它:
- 支持Lambda或方法引用,避免冗长分支逻辑
- 可预编译为静态函数对象,调用开销接近直接方法调用
- 与枚举常量绑定后,能实现编译期校验+运行时零判断跳转
- 便于组合(如map、andThen),适合链式策略或参数预处理
枚举定义:内置IntFunction并关联业务类型
枚举每个常量直接持有其对应的构建逻辑,不依赖外部工厂类:
public enum ResourceType {
A(1, AService::new, A::new),
B(2, BService::new, B::new),
C(3, CService::new, C::new);
private final int code;
private final IntFunction extends IService> serviceFactory;
private final IntFunction extends ResourceEntity> entityFactory;
ResourceType(int code,
IntFunction extends IService> serviceFactory,
IntFunction extends ResourceEntity> entityFactory) {
this.code = code;
this.serviceFactory = serviceFactory;
this.entityFactory = entityFactory;
}
public IService createService() {
return serviceFactory.apply(code);
}
public ResourceEntity createEntity() {
return entityFactory.apply(code);
}
public static ResourceType fromCode(int code) {
for (ResourceType t : values()) {
if (t.code == code) return t;
}
throw new IllegalArgumentException("Unknown code: " + code);
}
}
注意:构造器中传入的是方法引用(AService::new),JVM会将其编译为高效函数对象,而非每次调用都反射实例化。
使用方式:一行代码获取服务+实体
客户端无需关心类型转换或条件判断,语义清晰且类型安全:
// 根据整型码获取服务
IService service = ResourceType.fromCode(1).createService();
// 同时创建对应实体
ResourceEntity entity = ResourceType.fromCode(1).createEntity();
// 或组合使用(例如初始化后立即执行)
ResourceType.fromCode(2)
.createService()
.doFunc(ResourceType.fromCode(2).createEntity());
如果服务需Spring管理,可将IntFunction改为接受ApplicationContext,或在枚举中注入BeanFactory——但推荐保持枚举无状态,由外部注入依赖。
进阶:支持泛型约束与类型推导
若需强类型保障(如IService<a></a>),可引入泛型枚举(需类型擦除容忍)或分层设计:
- 定义泛型接口
<t extends resourceentity> IService<t></t></t> - 枚举常量声明为
A(1, JCmsAServiceImpl::new, A::new),其中构造器明确类型 - 工厂方法返回
IService<a></a>需配合类型令牌(如Class<a></a>)或使用Supplier替代IntFunction以规避泛型擦除限制
实际项目中,多数场景用非泛型基接口+运行时cast已足够,重点是把分支逻辑收束到枚举内部,保证扩展新增类型只需加一行枚举常量,不改任何if/switch。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











