.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技术站