一、为啥要搞 Function 工厂?你一定也有这种烦恼
有一个经典场景你肯定碰到过:
业务根据不同的类型做不同的处理,比如支付渠道、订单来源、消息类型、导出格式……
你可能最先写成这样👇:
if ("wechat".equals(type)) {
return handleWechat(data);
} else if ("alipay".equals(type)) {
return handleAlipay(data);
} else if ("unionpay".equals(type)) {
return handleUnionpay(data);
}
写起来简单,但一多起来,if-else
不光长得像楼梯,还特别不优雅!
二、目标:我希望把这堆 if-else 变成这样👇
Function<String, PayResult> handler = PayHandlerFactory.getHandler(type);
PayResult result = handler.apply(data);
是不是看起来清清爽爽?逻辑一目了然,还支持动态扩展!
三、思路:用 Function 做“处理器”,用 Map 做“仓库”
核心理念:
- • 每种类型对应一个 Function (处理逻辑);
- • 所有处理器注册到一个 Map;
- • 对外暴露一个 getHandler(type) 方法, 随查随用 。
我们现在就来手把手写一个“Function 处理器工厂”!
四、动手实现一个 Function 工厂(以支付渠道为例)
✅ Step 1:定义统一处理接口
@FunctionalInterface
public interface PayHandler extends Function<PayRequest, PayResult> {
}
或者你也可以直接用 Function<PayRequest, PayResult>
,为了清晰我这里封了一下接口。
✅ Step 2:定义处理逻辑(多个实现)
public class WechatPayHandler implements PayHandler {
@Override
public PayResult apply(PayRequest request) {
System.out.println("处理微信支付");
return new PayResult("微信支付成功");
}
}
public class AlipayHandler implements PayHandler {
@Override
public PayResult apply(PayRequest request) {
System.out.println("处理支付宝支付");
retur nnew PayResult("支付宝支付成功");
}
}
✅ Step 3:搞一个注册表(Map<String, Function>
)
public class PayHandlerFactory {
private static final Map<String, PayHandler> HANDLER_MAP = new HashMap<>();
static {
HANDLER_MAP.put("wechat", new WechatPayHandler());
HANDLER_MAP.put("alipay", new AlipayHandler());
}
public static PayHandler getHandler(String type) {
return Optional.ofNullable(HANDLER_MAP.get(type))
.orElseThrow(() -> new RuntimeException("找不到对应的支付处理器:" + type));
}
// 动态注册
public static void register(String type, PayHandler handler) {
HANDLER_MAP.put(type, handler);
}
}
你也可以用 ConcurrentHashMap
做线程安全的扩展,甚至在 Spring 中做自动注入。
✅ Step 4:使用方式超级清晰!
PayRequest request = new PayRequest("wechat");
PayHandler handler = PayHandlerFactory.getHandler(request.getType());
PayResult result = handler.apply(request);
System.out.println(result.getMessage());
添加新处理器?只要注册一次就好:
PayHandlerFactory.register("unionpay", req -> new PayResult("银联支付成功"));
五、更进一步:用 Function 写策略引擎都行!
比如你做了一个“用户标签打分系统”,你可以这样:
Map<String, Function<UserData, Integer>> scoreRules = new HashMap<>();
scoreRules.put("AGE", user -> user.getAge() > 30 ? 10 : 5);
scoreRules.put("GENDER", user -> "male".equals(user.getGender()) ? 8 : 6);
scoreRules.put("VIP", user -> user.isVip() ? 20 : 0);
// 计算总分
int total = scoreRules.values().stream()
.map(rule -> rule.apply(userData))
.reduce(0, Integer::sum);
是不是比传统方式更灵活?更少代码?更利于扩展?
六、再配合 Spring 用,自动注册不是梦!
用 @Component + @PostConstruct 实现自动注册:
@Component
public class WechatPayHandler implements PayHandler {
@PostConstruct
public void init() {
PayHandlerFactory.register("wechat", this);
}
@Override
public PayResult apply(PayRequest request) {
return new PayResult("Spring 自动注册的微信支付处理器");
}
}
你只需要写处理类,注册工厂自动搞定,再也不用动工厂代码!
七、总结:Function 工厂能做啥?
用法 | 描述 | 示例 |
替代 if-else | 将判断逻辑变成注册查表 | 支付渠道、导出格式 |
动态策略选择 | 多规则匹配处理 | 用户打标签、营销引擎 |
框架插件化 | 通过 Function 注入处理逻辑 | 消息中心、规则引擎 |
可测试、可替换 | Function 是函数对象,易 mock | 单测更容易 |
八、一句话总结:
有了 Function 工厂,if-else 去无踪,逻辑清晰易扩展,团队开发不打架,代码维护不头大!