策略模式(Strategy Pattern)深入解析与实战应用

策略模式(Strategy Pattern)深入解析与实战应用

策略模式是一种常见的行为型设计模式,常用于替代大量冗余的 if-else 或 switch-case 结构。它通过将一系列可互换的策略(行为)封装起来,使代码结构更清晰、可扩展性更强。

一、什么是策略模式?

策略模式(Strategy Pattern) 是指将一组算法或操作逻辑抽象为独立的"策略对象",根据上下文条件选择某一种策略执行。

一句话概括:把繁杂的 if-else 判断逻辑,变成"查表执行"。

二、策略模式结构图

plaintext

复制代码

┌────────────┐

│ Context │ ← 运行环境,持有策略并调用

└────┬───────┘

┌────────────┐

│ Strategy A │ ← 实现某个行为

└────────────┘

┌────────────┐

│ Strategy B │ ← 实现另一个行为

└────────────┘

在 JavaScript/TypeScript 中,我们通常用对象映射(Map)来实现策略模式。

三、为什么要使用策略模式?

问题

策略模式解决方案

逻辑混乱

将不同逻辑解耦封装

if/else 重复臃肿

使用映射对象替代判断

新增/修改逻辑易出错

可扩展、遵循开闭原则

单元测试困难

策略单元独立、易测试

四、策略模式实战案例

✅ 1. 表单校验策略

ts

复制代码

const validateMap = {

email: (val: string) => /\S+@\S+\.\S+/.test(val),

phone: (val: string) => /^1\d{10}$/.test(val),

username: (val: string) => val.length >= 3

};

function validate(type: string, value: string) {

const fn = validateMap[type];

return fn ? fn(value) : false;

}

✅ 2. Vue

动态视图策略

ts

复制代码

// strategies.ts

export const renderMap = {

list: () => ,

card: () => ,

table: () =>

}

vue

复制代码

🔁 五、从 if-else 到策略模式

原始写法(冗余):

ts

复制代码

function parseFile(type, content) {

if (type === 'json') return JSON.parse(content)

if (type === 'xml') return parseXML(content)

if (type === 'csv') return parseCSV(content)

throw new Error('Unknown type')

}

策略模式写法(优雅):

ts

复制代码

const parsers = {

json: JSON.parse,

xml: parseXML,

csv: parseCSV

}

function parseFile(type: string, content: string) {

const fn = parsers[type]

if (!fn) throw new Error('Unknown type')

return fn(content)

}

🧠 六、策略模式适用场景

多分支逻辑(if/else 或 switch)

规则判断:权限控制、表单验证、日志等级等

插件架构:支付方式、导出格式等

动态行为切换:主题切换、布局切换、组件渲染等

七、策略模式的进阶技巧

技巧

示例

支持注册/注销策略

StrategyMap.register('new', fn)

结合工厂模式

动态生成策略对象

封装为类或插件

统一维护,提升复用性

与配置驱动结合

使用配置文件/后端数据决定策略行为

八、与其他设计模式的区别

模式

相同点

区别

工厂模式

都封装行为创建

工厂关注对象创建,策略关注逻辑执行

状态模式

都有行为切换

状态模式强调状态变化,策略是行为选择

命令模式

都可执行操作

命令模式可撤销/排队,策略更偏向选择

✅ 九、总结

策略模式具有以下优点:

✅ 解耦逻辑,清晰可读

✅ 易于扩展,符合开闭原则

✅ 易于测试,策略函数天然可单测

✅ 非常适合动态渲染与业务逻辑分发

十、推荐封装方式(TypeScript 示例)

ts

复制代码

type StrategyFn = (args?: any) => any;

class StrategyManager {

private strategies: Record = {};

register(key: string, fn: StrategyFn) {

this.strategies[key] = fn;

}

execute(key: string, args?: any) {

const fn = this.strategies[key];

if (!fn) throw new Error(`No strategy for key: ${key}`);

return fn(args);

}

}

你可能也喜欢

中国邮政航空有几架飞机(EMS邮政航空怎么样)
音响行业汇
Bte365

音响行业汇

02-12 6354
海豚的智慧之谜:它们为什么比其他动物更聪明?