策略模式(Strategy Pattern)属于行为型设计模式。核心思路是将一组可替换的算法封装在独立的类中,使它们可以在运行时动态切换,同时使客户端代码与具体算法解耦。它包含三个核心角色:
通俗比喻:把算法当作「插件」,客户端只需要选择对应插件插入到主流程中,不需要关注插件内部实现。
_以下场景常见于前端开发:_
if-else
或 switch-case
的场景(如老代码中的支付方式处理)// 策略接口:定义 validate 方法
class ValidationStrategy {
validate(value) {
throw new Error("必须实现 validate 方法!");
}
}
// 具体策略:非空校验
class RequiredValidation extends ValidationStrategy {
validate(value) {
return value.trim() !== "";
}
}
// 具体策略:手机号校验
class MobileValidation extends ValidationStrategy {
validate(value) {
return /^1[3-9]\d{9}$/.test(value);
}
}
// 上下文类:管理当前策略
class ValidatorContext {
constructor(strategy) {
this.strategy = strategy;
}
setStrategy(strategy) {
this.strategy = strategy;
}
execute(value) {
return this.strategy.validate(value);
}
}
// 使用示例
const validator = new ValidatorContext(new RequiredValidation());
console.log(validator.execute("")); // 输出 false
validator.setStrategy(new MobileValidation());
console.log(validator.execute("13800138000")); // 输出 true
代码亮点:
ValidatorContext
.setStrategy()
动态切换算法// 策略接口:导出方法
class ExportStrategy {
export(data) {
throw new Error("必须实现 export 方法");
}
}
// 具体策略-导出为 CSV
class CsvExport extends ExportStrategy {
export(data) {
const csvContent = data.map(row => row.join(",")).join("\n");
console.log(`导出 CSV 成功,内容:${csvContent}`);
}
}
// 具体策略-导出为 Excel(伪代码)
class ExcelExport extends ExportStrategy {
export(data) {
// 假装调用了 Excel 库
console.log("生成 Excel 文件并下载");
}
}
// 上下文(可与 UI 结合)
class Exporter {
constructor() {
this.strategy = new CsvExport(); // 默认策略
}
setFormat(format) {
if (format === 'csv') {
this.strategy = new CsvExport();
} else if (format === 'excel') {
this.strategy = new ExcelExport();
}
}
executeExport(data) {
this.strategy.export(data);
}
}
// 使用示例
const exporter = new Exporter();
exporter.setFormat('excel');
exporter.executeExport([['Name', 'Age'], ['John', 30]]);
应用场景:
不同导出格式的代码集中到策略类中,避免主模块代码混乱。
interface Strategy {
execute(data: any): void;
}
MobileValidationStrategy
而非 Strategy1
,便于维护if-else
更简单value
,有的需要 formData
策略模式是应对算法多样化和动态切换需求的强大工具,前端开发中使用频率较高。
正确使用可显著提升代码可维护性,但在简单场景下需权衡是否引入复杂度。关键在于识别行为的变化点,将其独立出来。