if-else膨胀难维护的本质是职责错位,即策略选择与执行混杂;应通过工厂+策略模式解耦,定义统一接口、实现具体策略、用预注册Map工厂封装创建逻辑,使主流程简化为一行调用。
为什么 if\_else 膨胀后难维护,不是逻辑问题而是职责错位
当一个函数里出现 5 个以上
分支,且每个分支都在做「不同类型的处理」(比如不同支付方式、不同导出格式、不同审核规则),问题本质不是条件多,而是把「策略选择」和「策略执行」混在了一起。工厂模式负责解耦对象创建,策略模式负责解耦算法行为——两者配合,能把
从主流程里彻底摘出去。
用工厂 + 策略组合替换 if\_else 的三步实操
以「订单导出」为例:支持 Excel、PDF、CSV 三种格式,原逻辑类似:
替换成策略+工厂的关键动作:
定义统一策略接口
:
,含
方法
为每种类型实现策略类
:如
、
,都实现
用工厂封装创建逻辑
:写一个
,内部用
预注册所有策略实例(或按需 new);调用方只传
,工厂返回对应
之后主流程就只剩一行:
。新增格式只需加实现类 + 注册进工厂,不碰原有逻辑。
工厂注册策略时容易踩的坑
常见错误是把工厂写成静态方法 + 大量
,等于换汤不换药:
正确做法是避免运行时判断:
启动时用
预注册,key 是类型标识(如
),value 是策略实例(推荐单例)
注册来源可以是 Spring 的
+
,或手写
块初始化
如果策略需传参(如
),工厂里别硬编码路径,改用配置项或构造参数注入
务必检查
返回
的情况——建议抛
并带明确定义的错误码,而不是静默失败
策略类之间共享逻辑怎么抽?别动 factory,动 strategy
多个策略有共用代码(比如都需校验权限、都需记录日志),不要塞进工厂,也不要在每个策略里重复写。两种安全做法:
写一个
抽象类,把公共逻辑放
里,子类只覆写
用组合:策略类持有一个
,把校验、日志等作为独立服务注入,保持策略本身无状态
注意:别为了“复用”把策略类变成继承树过深,两层(抽象基类 + 具体实现)足够。超过三层,往往说明策略分类维度本身有问题。
真正难的从来不是写策略或工厂,而是厘清哪些该变(策略内容)、哪些不该变(策略选择机制)。一旦把
拆成可插拔的策略实例,后续加新分支就只是增文件、改配置,而不是翻旧代码、怕改崩。
if-elseif-elseif (type.equals("excel")) {
new ExcelExporter().export(orderList);
} else if (type.equals("pdf")) {
new PdfExporter().export(orderList);
} else if (type.equals("csv")) {
new CsvExporter().export(orderList);
}Exporterexport(List) ExcelExporterPdfExporterExporterExporterFactoryMaptypeExporterexporterFactory.getExporter(type).export(orderList)if-elsepublic static Exporter get(String type) {
if ("excel".equals(type)) return new ExcelExporter();
if ("pdf".equals(type)) return new PdfExporter();
// ……又来一遍 if-else
}Map"excel"@Bean@QualifierstaticPdfExporter(String templatePath)getExporter(type)nullIllegalArgumentExceptionBaseExportertemplateMethod()doExport()ExportHelperif-else