模式简介
定义一系列的算法, 把它们一个个封装起来, 并且使它们可互相替换. 本模式使得算法可独立于使用它的客户而变化.
策略模式也被称为政策模式, 它是一种行为型模式. 为了完成某一项任务, 往往可以有很多种不同的方式, 例如商场促销, 有不同的促销手段, 比如提价 50 满 100 减 20, 原价两倍打八折等等, 这每一种方式我们称之为策略. 为了避免将策略硬编码在程序当中, 可以使用策略模式, 在系统运行过程中根据具体的环境或者条件执行不同的策略.
结构分析
UML 类图
角色说明
Context
上下文类. 包含一个对 Strategy 对象的引用, 提供一个方法配置 ConcreteStrategy 对象, 实现算法的动态替换.
Strategy
策略接口. 定义算法的公共接口, Context 类通过这个接口调用具体策略的算法.
ConcreteStrategy
具体策略. 实现策略接口, 定义具体算法.
工作原理
Context 类提供一个方法 (SetStrategy) 设置具体算法, 并将该对象的引用保存到私有变量_strategy 中. Context 将客户端请求转发给_strategy 对象, 完成策略调用.
结构代码
- // 策略接口
- interface IStrategy
- {
- void AlgorithmInterface();
- }
- // 上下文类
- class Context
- {
- private IStrategy _strategy;
- public void SetStrategy(IStrategy strategy)
- {
- _strategy = strategy;
- }
- public void ContextInterface()
- {
- _strategy.AlgorithmInterface();
- }
- }
- // 具体策略 A
- class ConcreteStrategyA : IStrategy
- {
- public void AlgorithmInterface()
- {
- Console.WriteLine("Called ConcreteStrategyA.AlgorithmInterface()");
- }
- }
- // 具体策略 B
- class ConcreteStrategyB : IStrategy
- {
- public void AlgorithmInterface()
- {
- Console.WriteLine("Called ConcreteStrategyB.AlgorithmInterface()");
- }
- }
- // 客户端调用
- class Program
- {
- static void Main(string[] args)
- {
- Context context = new Context();
- context.SetStrategy(new ConcreteStrategyA());
- context.ContextInterface();
- context.SetStrategy(new ConcreteStrategyB());
- context.ContextInterface();
- Console.ReadLine();
- }
- }
程序输出:
示例分析
本节我们依然实现文章开头中的示例, 首先声明 ISalesPromotion 接口.
- public interface ISalesPromotion
- {
- void Calculate(int orgPrice);
- }
分别实现提价 50 满 100 减 20 以及原价两倍打八折两种销售策略.
- public class Reduction : ISalesPromotion
- {
- public void Calculate(int orgPrice)
- {
- var price = orgPrice + 50 - 20;
- Console.WriteLine($"Original Price : [{orgPrice}] , Price : [{price}]");
- }
- }
- public class Discount : ISalesPromotion
- {
- public void Calculate(int orgPrice)
- {
- var price = orgPrice * 2 * 0.8;
- Console.WriteLine($"Original Price : [{orgPrice}] , Price : [{price}]");
- }
- }
创建产品类
- public class Product
- {
- private ISalesPromotion _promotion;
- public void SetPromotion(ISalesPromotion promotion)
- {
- _promotion = promotion;
- }
- public void PrintPrice(int price)
- {
- _promotion.Calculate(price);
- }
- }
客户端调用
- class Program
- {
- static void Main(string[] args)
- {
- int price1 = 120;
- Product p1 = new Product();
- // 设置促销策略为满减
- p1.SetPromotion(new Reduction());
- p1.PrintPrice(price1);
- int price2 = 500;
- Product p2 = new Product();
- // 设置促销策略为打折
- p2.SetPromotion(new Discount());
- p2.PrintPrice(price2);
- Console.ReadLine();
- }
- }
程序输出
使用场景
许多相关的类仅仅时行为上有差异. 策略模式可以动态地让一个对象在众多行为中选择一种行为.
一个系统需要动态地在几种算法中选择一种.
一个对象有很多行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现.
不希望客户知道复杂的, 与算法相关的数据结构, 在具体策略类中封装算法和相关的数据结构, 提高算法的保密性及安全性.
来源: https://www.cnblogs.com/Answer-Geng/p/9356301.html