当前位置: 首页 > news >正文

TypeScript 中的策略模式

策略模式(Strategy Pattern)是一种行为设计模式,它允许你定义一系列算法,并将每个算法封装起来,使它们可以相互替换。下面介绍策略模式在 TypeScript 中的实现。

策略模式基本概念

策略模式包含三个主要部分:

  • Context(上下文):维护一个策略对象的引用
  • Strategy(策略接口):定义所有支持的算法的公共接口
  • ConcreteStrategy(具体策略):实现策略接口的具体算法

image

基础实现

1. 定义策略接口

// 策略接口
interface PaymentStrategy {pay(amount: number): void;
}

2. 实现具体策略类

// 信用卡支付策略
class CreditCardPayment implements PaymentStrategy {private cardNumber: string;private name: string;constructor(cardNumber: string, name: string) {this.cardNumber = cardNumber;this.name = name;}pay(amount: number): void {console.log(`使用信用卡支付 $${amount}`);console.log(`卡号: ${this.cardNumber}, 持卡人: ${this.name}`);}
}// PayPal支付策略
class PayPalPayment implements PaymentStrategy {private email: string;constructor(email: string) {this.email = email;}pay(amount: number): void {console.log(`使用PayPal支付 $${amount}`);console.log(`邮箱: ${this.email}`);}
}// 加密货币支付策略
class CryptoPayment implements PaymentStrategy {private walletAddress: string;constructor(walletAddress: string) {this.walletAddress = walletAddress;}pay(amount: number): void {console.log(`使用加密货币支付 $${amount}`);console.log(`钱包地址: ${this.walletAddress}`);}
}

3. 创建上下文类

// 支付上下文
class PaymentContext {private strategy: PaymentStrategy;constructor(strategy: PaymentStrategy) {this.strategy = strategy;}// 设置支付策略setStrategy(strategy: PaymentStrategy): void {this.strategy = strategy;}// 执行支付executePayment(amount: number): void {this.strategy.pay(amount);}
}

4. 使用示例

// 使用示例
const paymentContext = new PaymentContext(new CreditCardPayment("1234-5678-9012", "张三"));// 使用信用卡支付
paymentContext.executePayment(100);// 切换到PayPal支付
paymentContext.setStrategy(new PayPalPayment("zhang@example.com"));
paymentContext.executePayment(200);// 切换到加密货币支付
paymentContext.setStrategy(new CryptoPayment("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"));
paymentContext.executePayment(300);

更复杂的示例:排序策略

// 排序策略接口
interface SortStrategy<T> {sort(items: T[]): T[];
}// 冒泡排序策略
class BubbleSort<T> implements SortStrategy<T> {sort(items: T[]): T[] {console.log("使用冒泡排序");const arr = [...items];for (let i = 0; i < arr.length; i++) {for (let j = 0; j < arr.length - i - 1; j++) {if (arr[j] > arr[j + 1]) {[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];}}}return arr;}
}// 快速排序策略
class QuickSort<T> implements SortStrategy<T> {sort(items: T[]): T[] {console.log("使用快速排序");if (items.length <= 1) return items;const pivot = items[0];const left = [];const right = [];for (let i = 1; i < items.length; i++) {if (items[i] < pivot) {left.push(items[i]);} else {right.push(items[i]);}}return [...this.sort(left), pivot, ...this.sort(right)];}
}// 排序上下文
class Sorter<T> {private strategy: SortStrategy<T>;constructor(strategy: SortStrategy<T>) {this.strategy = strategy;}setStrategy(strategy: SortStrategy<T>): void {this.strategy = strategy;}sort(items: T[]): T[] {return this.strategy.sort(items);}
}// 使用示例
const numbers = [64, 34, 25, 12, 22, 11, 90];
const sorter = new Sorter<number>(new BubbleSort<number>());console.log("排序前:", numbers);
console.log("排序后:", sorter.sort(numbers));// 切换排序策略
sorter.setStrategy(new QuickSort<number>());
console.log("使用快速排序:", sorter.sort(numbers));

使用函数式编程的实现

TypeScript 也支持函数式风格的策略模式:

// 策略类型定义
type DiscountStrategy = (amount: number) => number;// 具体策略函数
const noDiscount: DiscountStrategy = (amount: number) => amount;const percentageDiscount = (percentage: number): DiscountStrategy => (amount: number) => amount * (1 - percentage / 100);const fixedDiscount = (discount: number): DiscountStrategy => (amount: number) => Math.max(0, amount - discount);// 上下文
class ShoppingCart {private items: number[] = [];private discountStrategy: DiscountStrategy = noDiscount;addItem(price: number): void {this.items.push(price);}setDiscountStrategy(strategy: DiscountStrategy): void {this.discountStrategy = strategy;}getTotal(): number {const subtotal = this.items.reduce((sum, price) => sum + price, 0);return this.discountStrategy(subtotal);}
}// 使用示例
const cart = new ShoppingCart();
cart.addItem(100);
cart.addItem(50);
cart.addItem(30);console.log("原价:", cart.getTotal()); // 180cart.setDiscountStrategy(percentageDiscount(10)); // 9折
console.log("9折后:", cart.getTotal()); // 162cart.setDiscountStrategy(fixedDiscount(50)); // 减50
console.log("减50后:", cart.getTotal()); // 130

策略模式的优点

  1. 开闭原则:可以引入新策略而不修改现有代码
  2. 消除条件语句:避免大量的 if-else 或 switch-case 语句
  3. 算法复用:可以在不同的上下文中复用策略
  4. 测试友好:每个策略都可以独立测试

适用场景

  • 一个系统需要在多种算法中选择一种时
  • 有多个条件语句来选择不同的行为时
  • 需要动态切换算法时
  • 希望将算法的使用与实现分离时

策略模式是非常实用的设计模式,特别适合处理需要灵活切换行为的场景。

参考资料

  • https://refactoring.guru/design-patterns/strategy
http://www.jsqmd.com/news/36653/

相关文章:

  • NProgress 给 Vue 路由切换加个 “假” 进度条提升用户体验
  • 2025年钢结构艺术造型直销厂家权威推荐榜单:钢结构景观造型/艺术钢结构/扭曲螺旋钢结构艺术造型源头厂家精选
  • 伊克罗德信息成为 Dify 官方代理商,携手共创企业级 Agentic AI 应用新未来!
  • 数组的定义、访问、输出
  • 2025年沼气直燃品牌综合评测:徐州海德测控领跑行业
  • 2025年沼气直燃生产厂家实力对比:徐州海德测控领跑
  • 2025年市场低氮燃烧器供应商前十强
  • 2025年沼气直燃品牌排名前十:徐州海德测控领跑行业创新
  • 2025年低氮燃烧器制造企业top10:行业排名与深度解析
  • 封装电气性能新径
  • 在Docker中live-restore
  • 11月10日打卡
  • 2025年11月安徽省矿用设备安全检测检验企业口碑榜
  • 从局部性原理到一致性模型:深入剖析缓存设计的核心权衡
  • P3625 采油区域-分类讨论
  • 12345A 景区 区别
  • 2025年贴标机生产厂家前十强权威排名:彩航包装领跑行业
  • FastApi Linux 部署
  • 方格染色-并查集
  • 逆向基础--数据传输指令mov和xchg (10)
  • P8186-传递闭包
  • MCU电路为什么要使用复位芯片?
  • 幂塔问题-扩展欧拉函数
  • P3623 免费道路 - Kruskal
  • 2025年11月安徽合肥正规的除甲醛平台推荐排行榜单
  • 2025年11月安徽合肥除甲醛服务商推荐排行榜前十名
  • 手持贴标机生产源头厂家2025年市场洞察
  • 2025年市场上水果打标枪生产厂家排名前十:陕西彩航包装领跑行业
  • 2025年水果打标枪生产厂家Top10排名:彩航包装装潢有限公司领跑行业
  • 关于在CASS软件中导入SHP文件时出现文字乱码问题的解决方案