如何在TypeScript中优雅处理超100种批量任务类型?
批量任务实例选型优化方案
问题背景
通过.env配置批量任务类型,用单个程序处理所有批量任务以避免重复配置CD,程序单次仅执行一种任务。初期任务少用if-else判断,10+任务后改用实现Batchable接口的类抽象逻辑,但目前任务超60种,getBatchClient里的switch-case代码超200行,按字母排序后查找维护困难。曾考虑用Map存储任务类型与实例映射,但提前创建所有实例会浪费内存;分层Map因任务类型无规律不可行。
最优解决方案推荐
1. 懒加载Map(Supplier实现)
不用提前创建所有任务实例,而是在Map中存储任务类的实例化逻辑(比如构造方法引用),当需要执行任务时才实例化对应的类,既避免了switch-case的冗长,又解决了内存浪费问题。
示例代码(Java为例):
// 定义映射关系:任务类型 -> 实例化Supplier private static final Map<String, Supplier<Batchable>> TASK_SUPPLIERS = Map.of( "AccountSync", AccountSyncTask::new, "OrderExport", OrderExportTask::new, "UserCleanup", UserCleanupTask::new // 按字母顺序添加其他任务,新增任务仅需追加一行 ); // 获取任务实例的方法 public Batchable getBatchClient(String batchType) { Supplier<Batchable> supplier = TASK_SUPPLIERS.get(batchType); if (supplier == null) { throw new IllegalArgumentException("无效的任务类型: " + batchType); } // 仅在调用get()时才创建实例 return supplier.get(); }
- 优势:实现简单,无额外依赖;仅初始化当前需要的任务实例,内存零浪费;新增/修改任务只需调整Map,维护成本远低于
switch-case。
2. 反射+自定义注解(自动化维护)
如果任务数量持续增长且频繁新增,可以用注解标记任务类,程序启动时自动扫描并构建映射关系,完全避免手动维护映射表。
示例代码:
// 自定义任务注解,标记任务类型 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface BatchTask { String type(); } // 任务类示例:用注解标记对应的任务类型 @BatchTask(type = "AccountSync") public class AccountSyncTask implements Batchable { @Override public void doBatch() { // 任务逻辑 } } // 初始化映射表(程序启动时执行) private static Map<String, Class<? extends Batchable>> TASK_CLASSES = new HashMap<>(); static { // 扫描指定包下所有带@BatchTask注解的类 Reflections reflections = new Reflections("com.your.company.batches"); Set<Class<?>> annotatedClasses = reflections.getTypesAnnotatedWith(BatchTask.class); for (Class<?> clazz : annotatedClasses) { BatchTask annotation = clazz.getAnnotation(BatchTask.class); TASK_CLASSES.put(annotation.type(), (Class<? extends Batchable>) clazz); } } // 获取任务实例 public Batchable getBatchClient(String batchType) throws Exception { Class<? extends Batchable> taskClass = TASK_CLASSES.get(batchType); if (taskClass == null) { throw new IllegalArgumentException("无效的任务类型: " + batchType); } // 延迟实例化任务类 return taskClass.getDeclaredConstructor().newInstance(); }
- 优势:新增任务仅需给类加注解,无需修改工厂类;自动扫描避免手动维护映射的错误;适合任务数量极多(比如上百种)的场景。
- 注意:需要引入反射工具包(如
org.reflections:reflections),反射实例化的性能损耗对批量离线任务可忽略。
方案对比与结论
- 继续用switch-case:不推荐,60+任务会导致代码臃肿,查找、修改易出错,维护成本随任务数量线性增长。
- 提前创建所有实例的Map:没必要,完全可以用懒加载替代,避免不必要的内存占用。
- 优先选懒加载Map(Supplier方式):平衡了实现复杂度和维护成本,是最通用的解决方案。
- 反射+注解:适合任务频繁新增的场景,最大化减少手动维护工作。
内容的提问来源于stack exchange,提问作者Giuk Kim
相关产品推荐
相关产品推荐

