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

设计模式 21 策略模式

设计模式 21

  • 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  • 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
  • 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

文章目录

  • 设计模式 21
    • 策略模式(Strategy Pattern)
      • 1 定义
      • 2 结构
      • 3 示例代码
      • 4 特点
      • 5 适用场景
      • 6 总结

策略模式(Strategy Pattern)

1 定义

策略模式的核心思想是将不同的算法或行为封装到独立的策略类中,并通过上下文类来管理和使用这些策略。客户端可以通过上下文类来动态选择使用哪种策略,而无需关心策略的具体实现细节。

2 结构

策略模式包含以下角色:

  • 上下文(Context): 维护一个策略对象的引用,供客户端使用。上下文不实现算法,而是将算法的实现委托给策略对象。
  • 策略接口(Strategy): 定义一组算法的通用接口,所有具体策略类都实现这个接口。
  • 具体策略(ConcreteStrategy): 实现策略接口,定义具体的算法或行为。

UML 类图

+---------------------------+       +-----------------------+
|      Context              |       |      Strategy         |
+---------------------------+       +-----------------------+
| - strategy: Strategy      |       | + Algorithm(): void   |
| + SetStrategy(Strategy)   |       +-----------------------+
| + ExecuteStrategy(): void |           ^              ^
+---------------------------+           |              ||              ||              |+-----------------------+        +-----------------------+| ConcreteStrategyA     |        | ConcreteStrategyB     |+-----------------------+        +-----------------------+| + Algorithm(): void   |        | + Algorithm(): void   |+-----------------------+        +-----------------------+

3 示例代码

假设我们要实现一个简单的支付系统,它支持多种支付方式,如信用卡支付、PayPal支付和比特币支付。我们可以使用策略模式来封装这些支付方式,并让客户端在运行时选择不同的支付策略。

策略接口

// 策略接口
public interface IPaymentStrategy
{void Pay(double amount);
}

具体策略类

// 具体策略 - 信用卡支付
public class CreditCardPayment : IPaymentStrategy
{private string _cardNumber;public CreditCardPayment(string cardNumber){_cardNumber = cardNumber;}public void Pay(double amount){Console.WriteLine($"Paid {amount} using Credit Card {_cardNumber}.");}
}// 具体策略 - PayPal支付
public class PayPalPayment : IPaymentStrategy
{private string _email;public PayPalPayment(string email){_email = email;}public void Pay(double amount){Console.WriteLine($"Paid {amount} using PayPal account {_email}.");}
}// 具体策略 - 比特币支付
public class BitcoinPayment : IPaymentStrategy
{private string _walletAddress;public BitcoinPayment(string walletAddress){_walletAddress = walletAddress;}public void Pay(double amount){Console.WriteLine($"Paid {amount} using Bitcoin wallet {_walletAddress}.");}
}

上下文类

// 上下文类
public class PaymentContext
{private IPaymentStrategy _paymentStrategy;public void SetPaymentStrategy(IPaymentStrategy paymentStrategy){_paymentStrategy = paymentStrategy;}public void Pay(double amount){_paymentStrategy.Pay(amount);}
}

客户端代码

class Program
{static void Main(string[] args){PaymentContext context = new PaymentContext();// 使用信用卡支付context.SetPaymentStrategy(new CreditCardPayment("1234-5678-9012-3456"));context.Pay(100.0);// 使用PayPal支付context.SetPaymentStrategy(new PayPalPayment("user@example.com"));context.Pay(200.0);// 使用比特币支付context.SetPaymentStrategy(new BitcoinPayment("1BitcoinAddressXYZ"));context.Pay(300.0);}
}

运行结果

Paid 100 using Credit Card 1234-5678-9012-3456.
Paid 200 using PayPal account user@example.com.
Paid 300 using Bitcoin wallet 1BitcoinAddressXYZ.

在这个例子中,PaymentContext 是上下文类,它持有一个 IPaymentStrategy 策略接口的引用。客户端可以动态设置不同的支付策略,如 CreditCardPaymentPayPalPaymentBitcoinPayment,并通过 Pay() 方法执行支付操作。这样,支付方式的变化不会影响客户端代码。

4 特点

  • 优点:

    • 算法的灵活性: 策略模式允许在运行时选择不同的算法或行为,增加了系统的灵活性和扩展性。

    • 避免使用条件语句: 通过将不同的算法封装在独立的策略类中,避免了在客户端代码中使用大量的条件分支语句。

    • 遵循开放-封闭原则: 可以在不修改现有代码的情况下,通过添加新的策略类来扩展系统的功能。

  • 缺点:

    • 增加类的数量: 每个策略都需要一个具体的策略类,可能会导致类的数量增加,增加系统的复杂性。

    • 策略选择的复杂性: 在一些情况下,策略的选择逻辑可能本身就比较复杂,如何选择合适的策略可能会成为一个挑战。

5 适用场景

  • 多种算法需要互换: 当一个系统有多个相似的算法或行为,并且这些算法或行为需要在不同情况下互换使用时,策略模式非常适用。
  • 消除条件分支语句: 如果代码中存在大量的条件分支语句来选择不同的算法或行为,策略模式可以通过将这些算法封装到独立的策略类中来简化代码。
  • 算法的频繁变化: 当算法或行为经常发生变化时,可以使用策略模式,使得每种算法封装在独立的策略类中,便于维护和扩展。

6 总结

策略模式通过将不同的算法封装到独立的策略类中,实现了算法的灵活互换。它消除了大量的条件分支语句,使代码更加清晰和可扩展。尽管策略模式可能会增加类的数量,但它为系统的算法选择和扩展提供了一种灵活且强大的解决方案。在需要灵活选择算法或行为的场景中,策略模式是一种非常有效的设计模式。


http://www.mrgr.cn/news/22657.html

相关文章:

  • Windows磁盘文件恢复工具
  • 数据结构C //线性表ADT结构及相关函数
  • 国内低代码平台有哪些
  • 【Qt】事件分发器
  • 研究生论文开题报告撰写指南以及和任务书的区别是什么
  • 华为OD机试真题-字符串化繁为简-2024年OD统一考试(E卷)
  • 18057 ASCII码值之和的差
  • SuiNS的成就与未来愿景
  • Qt下载,离线安装
  • Python3 网络编程
  • Linux-------基础
  • agentuniverse快速开始和踩坑
  • 中亚五国认证制度体系,认证科普!
  • 如何把微信小程序添加到电脑桌面?
  • 优化销售流程:免费体验企元数智小程序合规分销系统!
  • GMT绘图笔记:在地图上绘制直线而不是大圆弧
  • 盛元广通医药行业实验室设备管理系统
  • C语言 ——— 宏和函数的区别
  • 第18届世界杰出华人奖得主王傲山:承父业展关怀,体现“圆桌”精神
  • javaString数据类型