.Net行为型设计模式之策略模式(Stragety)

.Net行为型设计模式之策略模式(Strategy)

策略模式概述

策略模式是一种行为型设计模式,它定义了一系列算法,并且将每个算法封装起来,使得它们可以互相替换。策略模式让算法的变化独立于使用它们的客户端。

策略模式的组成

策略模式由以下几个部分组成:

  • Context:上下文对象,它持有一个具体策略的引用,并调用具体策略的算法。
  • Strategy:策略接口,它定义了一个算法族,包括多个具体策略算法。
  • ConcreteStrategy:具体策略类,实现了策略接口,并提供了一种具体的算法实现。

策略模式的应用场景

策略模式通常用于以下两种情况:

  • 当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,可以使用策略模式。
  • 如果类的某个行为有多种实现方式,并且这些方式可以相对自由地切换,可以采用策略模式,封装这些实现并通过上下文来控制实现方式的切换。

策略模式示例

下面是一个简单的示例,其中Context是一个来自电商领域的订单对象,订单有一个总金额(totalAmount)属性,并计算订单的折扣(discount),然后根据应用的优惠策略计算出最终金额(finalAmount)。

public class Order {
    public decimal TotalAmount { get; set; }
    public decimal Discount { get; set; }
    public decimal FinalAmount { get; set; }
}

public interface IDiscountStrategy {
    decimal ApplyDiscount(decimal totalAmount);
}

public class NoDiscountStrategy : IDiscountStrategy {
    public decimal ApplyDiscount(decimal totalAmount) {
        return totalAmount;
    }
}

public class Discount10PercentStrategy : IDiscountStrategy {
    public decimal ApplyDiscount(decimal totalAmount) {
        return totalAmount * 0.9m;
    }
}

public class Discount50PercentStrategy : IDiscountStrategy {
    public decimal ApplyDiscount(decimal totalAmount) {
        return totalAmount * 0.5m;
    }
}

public class OrderService {
    private IDiscountStrategy _discountStrategy;

    public OrderService(IDiscountStrategy discountStrategy) {
        _discountStrategy = discountStrategy;
    }

    public Order Calculate(Order order) {
        order.Discount = _discountStrategy.ApplyDiscount(order.TotalAmount);
        order.FinalAmount = order.TotalAmount - order.Discount;
        return order;
    }
}

在该示例中,IDiscountStrategy是策略接口,它定义了ApplyDiscount方法,具体的策略实现类(NoDiscountStrategy、Discount10PercentStrategy、Discount50PercentStrategy)实现了该方法,并提供了不同的折扣策略。OrderService是上下文对象,该对象通过构造函数注入具体的策略实现对象,并在Calculate方法中使用该对象执行具体的折扣计算。

另外一个示例是对文件进行压缩和解压缩:

public interface ICompressionStrategy {
    void Compress(string sourceFile, string compressedFile);
    void Decompress(string compressedFile, string targetFile);
}

public class ZipCompressionStrategy : ICompressionStrategy {
    public void Compress(string sourceFile, string compressedFile) {
        Console.WriteLine($"Compressing {sourceFile} using ZIP format to {compressedFile}");
    }
    public void Decompress(string compressedFile, string targetFile) {
        Console.WriteLine($"Decompressing {compressedFile} using ZIP format to {targetFile}");
    }
}
public class RarCompressionStrategy : ICompressionStrategy {
    public void Compress(string sourceFile, string compressedFile) {
        Console.WriteLine($"Compressing {sourceFile} using RAR format to {compressedFile}");
    }
    public void Decompress(string compressedFile, string targetFile) {
        Console.WriteLine($"Decompressing {compressedFile} using RAR format to {targetFile}");
    }
}

public class CompressionContext {
    private ICompressionStrategy _strategy;
    public CompressionContext(ICompressionStrategy strategy) {
        _strategy = strategy;
    }
    public void SetStrategy(ICompressionStrategy strategy) {
        _strategy = strategy;
    }

    public void Compress(string sourceFile, string compressedFile) {
        _strategy.Compress(sourceFile, compressedFile);
    }

    public void Decompress(string compressedFile, string targetFile) {
        _strategy.Decompress(compressedFile, targetFile);
    }
}

在该示例中,ICompressionStrategy是策略接口,它定义了Compress和Decompress方法。具体的策略实现类(ZipCompressionStrategy和RarCompressionStrategy)实现了该方法,并提供了不同的压缩和解压缩策略。CompressionContext是上下文对象,通过构造函数或者SetStrategy方法注入具体的策略实现对象,并在Compress和Decompress方法中使用该对象执行具体的压缩和解压缩操作。

策略模式的优点

策略模式具有以下优点:

  • 算法可以自由互换,策略模式符合“开闭原则”,可以很方便地新增、替换和删除算法实现类。
  • 策略模式消除了大量的条件语句,提高了代码的可读性和可维护性。
  • 策略模式将算法的实现从客户端代码中分离出来,降低了耦合度。

策略模式的缺点

策略模式比较容易产生过多的策略类,如果不加以控制会导致维护成本增加。同时,策略类会影响到程序的结构,需要在程序初始化时就将所有的策略类准备好,增加了程序的复杂度。

以上为策略模式的完整攻略和示例,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:.Net行为型设计模式之策略模式(Stragety) - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • JS实现简单的二元方程计算器功能示例

    下面我会详细讲解如何实现一个简单的二元方程计算器功能。 1.需求分析 首先,我们需要明确我们要实现什么功能。这个简单的二元方程计算器要能够接收用户输入的两个数值,然后进行加、减、乘、除运算,并将计算结果输出给用户。 2.实现步骤 2.1 创建HTML文件和JS文件 首先,我们需要创建一个HTML文件和一个JS文件。HTML文件用来布局和展示界面,JS文件用来…

    C 2023年5月22日
    00
  • c语言main函数使用及其参数介绍

    C语言main函数使用及其参数介绍 在C语言程序中,主函数(main函数)是程序的入口,它负责整个程序的执行。main函数的形式如下: int main(int argc, char *argv[]) { //程序语句 return 0; } main函数包括三部分,分别是函数头、函数体和返回值。下面我们对这三部分进行详细介绍。 一、函数头 main函数的函…

    C 2023年5月23日
    00
  • C/C++中宏定义(#define)

    C/C++中宏定义(#define) 什么是宏定义? 在C/C++中,宏定义是一种预处理指令,用于让编译器在编译源代码之前进行一些简单的文本替换操作。定义完成后,程序中所有出现该定义的地方都会被替换成定义时所指定的文本内容。 宏定义的语法 #define 宏名称 宏取值 其中,“#define”是宏定义的关键字,“宏名称”是您定义的宏名称,“宏取值”则是您希…

    C 2023年5月23日
    00
  • C++实现简单射击小游戏

    C++实现简单射击小游戏攻略 1. 游戏规则 本游戏的规则如下: 游戏分为若干轮,每轮有若干个目标,目标会随机移动。 玩家需要使用键盘上的箭头键来移动瞄准器,使用空格键来射击。 每轮结束后,显示本轮的得分,并提示是否继续游戏。 2. 实现步骤 2.1 游戏框架搭建 游戏框架主要包括三个类:游戏引擎类(GameEngine)、目标类(Target)和玩家类(P…

    C 2023年5月23日
    00
  • C 程序 查找最大的三个数字

    作为网站的作者,我很高兴向你展示使用C语言实现在一个数组中查找最大的三个数字的完整攻略。下面是具体的步骤: 步骤一:定义数组 首先,我们需要定义一个包含数字的数组,这个数组可以是任何大小,这里我们定义一个包含10个元素的数组,数组中的元素分别为:10, 20, 30, 40, 50, 60, 70, 80, 90, 100。 int arr[10] = {1…

    C 2023年5月9日
    00
  • C语言系统调用约定

    C语言系统调用约定 在C语言中,系统调用使得程序能够与操作系统进行交互,包括执行I/O操作、内存管理等等。C语言中的系统调用约定是指C语言程序如何调用操作系统提供的系统调用。在不同的操作系统中,系统调用的约定可能不同,因此我们需要针对不同的操作系统学习和使用不同的系统调用约定。 基本概念 在C语言中,我们可以使用syscall函数进行系统调用。syscall…

    C 2023年5月23日
    00
  • 详解c++ atomic原子编程中的Memory Order

    当使用C++中的原子类型进行编程时,需要指定原子操作的内存顺序(Memory Order),以保证多线程下的正确性和一致性。 C++中原子操作的内存顺序一共有4种: memory_order_relaxed:最轻松的内存顺序,不会保证原子操作的顺序,也不保证操作的内存可见性。当我们要进行仅仅是读写共享内存而无需考虑同步问题的操作时,可以使用memory_or…

    C 2023年5月23日
    00
  • C语言程序 演示fork()和pipe()

    C语言程序演示fork()和pipe()的使用攻略 什么是fork()和pipe()? fork()是在Linux系统中用来创建新进程的系统调用函数。使用fork()函数可以创建出一个子进程,该子进程是父进程的一个副本,且会与父进程一同运行,但是有不同的pid和返回值。fork()函数被调用时,当前进程将会被复制一份,形成一个新的进程和父进程同步进行。新的进…

    C 2023年5月9日
    00
合作推广
合作推广
分享本页
返回顶部