找回密码
 立即注册
首页 业界区 业界 TypeScript 中的策略模式

TypeScript 中的策略模式

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

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

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

基础实现

1. 定义策略接口
  1. // 策略接口
  2. interface PaymentStrategy {
  3.   pay(amount: number): void;
  4. }
复制代码
2. 实现具体策略类
  1. // 信用卡支付策略
  2. class CreditCardPayment implements PaymentStrategy {
  3.   private cardNumber: string;
  4.   private name: string;
  5.   constructor(cardNumber: string, name: string) {
  6.     this.cardNumber = cardNumber;
  7.     this.name = name;
  8.   }
  9.   pay(amount: number): void {
  10.     console.log(`使用信用卡支付 $${amount}`);
  11.     console.log(`卡号: ${this.cardNumber}, 持卡人: ${this.name}`);
  12.   }
  13. }
  14. // PayPal支付策略
  15. class PayPalPayment implements PaymentStrategy {
  16.   private email: string;
  17.   constructor(email: string) {
  18.     this.email = email;
  19.   }
  20.   pay(amount: number): void {
  21.     console.log(`使用PayPal支付 $${amount}`);
  22.     console.log(`邮箱: ${this.email}`);
  23.   }
  24. }
  25. // 加密货币支付策略
  26. class CryptoPayment implements PaymentStrategy {
  27.   private walletAddress: string;
  28.   constructor(walletAddress: string) {
  29.     this.walletAddress = walletAddress;
  30.   }
  31.   pay(amount: number): void {
  32.     console.log(`使用加密货币支付 $${amount}`);
  33.     console.log(`钱包地址: ${this.walletAddress}`);
  34.   }
  35. }
复制代码
3. 创建上下文类
  1. // 支付上下文
  2. class PaymentContext {
  3.   private strategy: PaymentStrategy;
  4.   constructor(strategy: PaymentStrategy) {
  5.     this.strategy = strategy;
  6.   }
  7.   // 设置支付策略
  8.   setStrategy(strategy: PaymentStrategy): void {
  9.     this.strategy = strategy;
  10.   }
  11.   // 执行支付
  12.   executePayment(amount: number): void {
  13.     this.strategy.pay(amount);
  14.   }
  15. }
复制代码
4. 使用示例
  1. // 使用示例
  2. const paymentContext = new PaymentContext(new CreditCardPayment("1234-5678-9012", "张三"));
  3. // 使用信用卡支付
  4. paymentContext.executePayment(100);
  5. // 切换到PayPal支付
  6. paymentContext.setStrategy(new PayPalPayment("zhang@example.com"));
  7. paymentContext.executePayment(200);
  8. // 切换到加密货币支付
  9. paymentContext.setStrategy(new CryptoPayment("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"));
  10. paymentContext.executePayment(300);
复制代码
更复杂的示例:排序策略
  1. // 排序策略接口
  2. interface SortStrategy<T> {
  3.   sort(items: T[]): T[];
  4. }
  5. // 冒泡排序策略
  6. class BubbleSort<T> implements SortStrategy<T> {
  7.   sort(items: T[]): T[] {
  8.     console.log("使用冒泡排序");
  9.     const arr = [...items];
  10.     for (let i = 0; i < arr.length; i++) {
  11.       for (let j = 0; j < arr.length - i - 1; j++) {
  12.         if (arr[j] > arr[j + 1]) {
  13.           [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
  14.         }
  15.       }
  16.     }
  17.     return arr;
  18.   }
  19. }
  20. // 快速排序策略
  21. class QuickSort<T> implements SortStrategy<T> {
  22.   sort(items: T[]): T[] {
  23.     console.log("使用快速排序");
  24.     if (items.length <= 1) return items;
  25.    
  26.     const pivot = items[0];
  27.     const left = [];
  28.     const right = [];
  29.    
  30.     for (let i = 1; i < items.length; i++) {
  31.       if (items[i] < pivot) {
  32.         left.push(items[i]);
  33.       } else {
  34.         right.push(items[i]);
  35.       }
  36.     }
  37.    
  38.     return [...this.sort(left), pivot, ...this.sort(right)];
  39.   }
  40. }
  41. // 排序上下文
  42. class Sorter<T> {
  43.   private strategy: SortStrategy<T>;
  44.   constructor(strategy: SortStrategy<T>) {
  45.     this.strategy = strategy;
  46.   }
  47.   setStrategy(strategy: SortStrategy<T>): void {
  48.     this.strategy = strategy;
  49.   }
  50.   sort(items: T[]): T[] {
  51.     return this.strategy.sort(items);
  52.   }
  53. }
  54. // 使用示例
  55. const numbers = [64, 34, 25, 12, 22, 11, 90];
  56. const sorter = new Sorter<number>(new BubbleSort<number>());
  57. console.log("排序前:", numbers);
  58. console.log("排序后:", sorter.sort(numbers));
  59. // 切换排序策略
  60. sorter.setStrategy(new QuickSort<number>());
  61. console.log("使用快速排序:", sorter.sort(numbers));
复制代码
策略模式的优点


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


  • 一个系统需要在多种算法中选择一种时
  • 有多个条件语句来选择不同的行为时
  • 需要动态切换算法时
  • 希望将算法的使用与实现分离时
策略模式是非常实用的设计模式,特别适合处理需要灵活切换行为的场景。
参考资料


  • https://refactoring.guru/design-patterns/strategy

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册