跳转到主内容
极星编程网:以代码为星,赴技术山海!

如何利用工厂模式与策略模式消除代码中臃肿的if_else

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

相关文章