策略模式(Strategy Pattern)是一种行为设计模式,它允许你定义一系列算法,并将每个算法封装起来,使它们可以相互替换。下面介绍策略模式在 TypeScript 中的实现。
策略模式基本概念
策略模式包含三个主要部分:
- Context(上下文):维护一个策略对象的引用
- Strategy(策略接口):定义所有支持的算法的公共接口
- ConcreteStrategy(具体策略):实现策略接口的具体算法
基础实现
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));
复制代码 策略模式的优点
- 开闭原则:可以引入新策略而不修改现有代码
- 消除条件语句:避免大量的 if-else 或 switch-case 语句
- 算法复用:可以在不同的上下文中复用策略
- 测试友好:每个策略都可以独立测试
适用场景
- 一个系统需要在多种算法中选择一种时
- 有多个条件语句来选择不同的行为时
- 需要动态切换算法时
- 希望将算法的使用与实现分离时
策略模式是非常实用的设计模式,特别适合处理需要灵活切换行为的场景。
参考资料
- https://refactoring.guru/design-patterns/strategy
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |