首页 > 其他分享 >设计模式 21 策略模式

设计模式 21 策略模式

时间:2024-09-09 11:52:04浏览次数:14  
标签:21 Pay void 模式 算法 设计模式 public 策略

设计模式 21

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

文章目录

策略模式(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("[email protected]"));
        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 [email protected].
Paid 300 using Bitcoin wallet 1BitcoinAddressXYZ.

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

4 特点

  • 优点:

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

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

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

  • 缺点:

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

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

5 适用场景

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

6 总结

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

标签:21,Pay,void,模式,算法,设计模式,public,策略
From: https://blog.csdn.net/szy13323042191/article/details/142055393

相关文章

  • 《DNK210使用指南 -CanMV版 V1.0》第二十三章 六轴传感器——姿态解算实验
    第二十三章六轴传感器——姿态解算实验1)实验平台:正点原子DNK210开发板2)章节摘自【正点原子】DNK210使用指南-CanMV版V1.03)购买链接:https://detail.tmall.com/item.htm?&id=7828013987504)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/k210/ATK-DNK2......
  • day21
    非递减子序列classSolution{public:voidbacktracking(vector&nums,intstart){if(path.size()>1){ret.push_back(path);}if(start==nums.size()){return;}unordered_setuset;for(inti=start;i<nums.size();++i){if((!path.empty()&......
  • 如何在Spark键值对数据中,对指定的Key进行输出/筛选/模式匹配
    在用键值对RDD进行操作时,经常会遇到不知道如何筛选出想要数据的情况,这里提供了一些解决方法目录1、对固定的Key数据进行查询2、对不固定的Key数据进行模糊查询1、对固定的Key数据进行查询代码说明:SparkConf:配置Spark应用程序的一些基本信息。SparkContext:创建Spark......
  • LivePortrait: 让静态图像“活”起来、更好地控制图片/视频中人物的表情,新增动物模式,
     引言随着AI技术的飞速发展,图像生成与编辑的门槛不断降低,尤其在人像视频生成领域取得了令人瞩目的成就。快手可灵大模型团队开源的LivePortrait框架,以其出色的性能与创新的设计,引领了AI生成的新浪潮。LivePortrait不仅能够将静态图像转换为动态视频,还能精确控制面......
  • [LeetCode] 2181. Merge Nodes in Between Zeros
    Youaregiventheheadofalinkedlist,whichcontainsaseriesofintegersseparatedby0's.ThebeginningandendofthelinkedlistwillhaveNode.val==0.Foreverytwoconsecutive0's,mergeallthenodeslyinginbetweenthemintoasing......
  • 通风天窗18J621-3
    18J621-3《通风天窗》是中国国家建筑标准设计图集的一部分,为建筑设计师提供了关于通风天窗设计的标准化参考和指导。这本图集是替代了旧版05J621-3的标准,由权威机构中国建筑标准设计研究院组织编制,并由中国计划出版社出版发行。以下是对这本图集的详细介绍,为建筑设计师提供全......
  • 整车低压电源模式介绍
    引言  在日新月异的汽车行业中,有老牌车企不断推出新品牌,也出现了许多新势力车企。在这种市场环境下,各个车型的功能及其实现方式会存在许多的差异。本篇文章主要给大家介绍的是低压电源模式,希望能对大家有所帮助。  一、电源模式概述  整车低压电源模式是指整车上电......
  • 工厂模式和策略模式区别
    在技术圈的讨论里,不少程序员对工厂模式和策略模式产生了一些误解。有位老哥直接发帖:“这俩模式不就是一样的嘛?”听到这话,不少人都忍不住发出冷笑。就像有人把炒菜和火锅当成同一个做法——都是锅里煮出来的,能一样吗?所以,今天我们来聊聊这两个模式的区别,顺便用更接地气的例子,......
  • 在Java服务端实现策略模式:如何灵活应对业务逻辑的多变性
    在Java服务端实现策略模式:如何灵活应对业务逻辑的多变性大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在Java服务端开发中,业务逻辑的复杂性和多变性常常需要灵活的设计模式来应对。策略模式是一种经典的设计模式,用于定义一系列算法,将每一个算法封装......
  • 20240909_021725 c语言 骨架结构
    关注骨架结构明确intmainreturn0的意义与功能......