《设计模式》—— 策略模式 | C#实现

举个栗子

小明要设计一个计算器程序,要考虑加减乘除四则运算,对于程序来说,就是把变量放到正确的位置进行计算得出结果。不管是做什么运算,本质都是输入数字,得出结果。相同的是输入数字,不同的是运算符,那么这里就有不同的算法策略👇

设计原则

  • 找出应用之中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起
  1. 把变化的部分取出 封装 起来,好让其他部分不受到影响!这样可以应对代码变化,系统更加具有弹性!
  2. 把会变化的部分取出来并封装起来,方便后续改动或者扩充此部分,而不影响不需要变化的其他部分
  3. 每个设计模式背后的思想:系统中的某部分改变不会影响其他部分!
  • 针对接口编程,而不是针对实现编程
  1. 让一切具有弹性,运行时动态改变对象的行为!
  2. 具对象不用实现行为,由接口实现行为,对象不需要知道行为其中的细节
  3. 把某一行为抽象成接口,具体实现这个行为的类继承该接口
  4. 针对超类型编程,变量的声明类型是超类型:抽象类或者接口,只要具体实现此超类型的类们,都可用被指派给超类型变量,在声明类时,不用理会后续执行的真正对象类型

解决问题

  • 同一类型做不同行为,解决使用继承实现代码 复用 带来的缺陷
  • 让代码具有弹性,修改一个行为不影响其他行为也方便添加新行为
  • 行为写在(绑死)具体对象类中,需要修改更多代码修改行为或者增减行为,容易bug

针对接口与针对实现区别

针对实现编程:若声明变量 aAdd 类型,则必须要具体实现 Add 类型,但其实 AddOperation 的具体实现

Add a = new Add();
a.ExcuteAdd(n1, n2);

针对接口/超类型编程做法:我们知道对象是狗,但是我们不用 Add 来定义,我们用 Operation 进行多态调用!

Operation operation = new Operation();
Operation.Excute();

子类实例化不需要编码,可以在运行时指定具体实现对象,我们不关心实际的子类型是什么,我们只需要知道它可以进行Operation行为!

a = getOperation();
a.Excute(); 

优劣势适用场合

优点
  1. 可以自由切换,动态改变对象的行为
  2. 避免多重的if…else…判断
  3. 扩展性良好,简单方便
缺点
  1. 策略类增多,代码多
  2. 具体类要知道并决定使用哪个策略类
适用
  1. 如果在一个系统里面有许多相似的类,区别只在于行为不同,可以使用策略模式动态地让一个类选择多种/一种行为。
  2. 一个系统需要动态地在几种算法中选择一种,那么每个策略就是一种算法
  3. 若一个对象有多种行为也不用恰当的模式,这些行为只能用多重的条件选择语句来实现。

注意! 如果一个系统的策略多于4个!就要考虑使用混合模式,解决策略类的膨胀问题!

具体实现

类图

操作接口,Strategy 定义方法,所有实现接口的类都需要重写 doOperation()
在这里插入图片描述
Context 是使用了某种策略的类,executeStrategy 是执行某种行为,Context 在配置或者使用策略改变时,行为可以自由变换
在这里插入图片描述

C#实现代码
1. 创建接口

IStrategy.cs

interface IStrategy
    {
        int DoOperation(int num1, int num2);
    }
2. 创建实现接口的实体类

OperationAdd.cs

class OperationAdd : IStrategy
    {
        public int DoOperation(int num1, int num2)
        {
            //throw new NotImplementedException();
            int sum = num2 + num1;
            Console.Write("do OperationAdd [做加法运算]: " + num1 + " + " + num2 + " = " + sum + "\n");
            return sum;
        }
    }

OperationSubtract.cs

class OperationSubtract : IStrategy
    {
        public int DoOperation(int num1, int num2)
        {
            //throw new NotImplementedException();
            int res = num1 - num2;
            Console.Write("do OperationSubtract [做减法运算]:" + num1 + " - " + num2 + " = " + res + "\n");
            return res;
        }
    }

OperationMultiply.cs

class OperationMultiply : IStrategy
    {
        public int DoOperation(int num1, int num2)
        {
            // 乘法
            //throw new NotImplementedException();
            int res = num1 * num2;
            Console.Write("do OperationMultiply [做乘法运算]:" + num1 + " × " + num2 + " = "+ res + "\n");
            return res;
        }
    }
3. 创建Context类

Context.cs

IStrategy strategy;
public Context(IStrategy strategy)
{
    this.strategy = strategy;
}

public int ExecuteStrategy(int num1,int num2)
{
    return this.strategy.DoOperation(num1, num2);
}
4. 使用Context来查看当它改变策略 Strategy 时的行为变化

Program.cs

class Program
    {
        static void Main(string[] args)
        {
            int num1 = 10;
            int num2 = 20;
    
            StrategyContext AddContext = new StrategyContext(new OperationAdd());
            int sum = AddContext.ExecuteStrategy(num1, num2);
            Console.Write("AddContext ExecuteStrategy Result is:" + sum + "\n\n");
            
            StrategyContext MultiplyContext = new StrategyContext(new OperationMultiply());
            int multiply = MultiplyContext.ExecuteStrategy(num1, num2);
            Console.Write("MultiplyContext ExecuteStrategy Result is:" + multiply + "\n\n");
                
            StrategyContext SubtractContext = new StrategyContext(new OperationSubtract());
            int subtract = SubtractContext.ExecuteStrategy(num1, num2);
            Console.Write("SubtractContext ExecuteStrategy Result:" + subtract + "\n\n");

            Console.ReadKey();
        }
    }
5. 执行程序,输出结果
do OperationAdd [做加法运算]: 10 + 20 = 30
AddContext ExecuteStrategy Result is:30

do OperationMultiply [做乘法运算]:10 × 20 = 200
MultiplyContext ExecuteStrategy Result is:200

do OperationSubtract [做减法运算]:10 - 20 = -10
SubtractContext ExecuteStrategy Result:-10

在这里插入图片描述

参考
  1. 《Head First设计模式》
  2. 策略模式| 菜鸟教程
  3. 策略模式|极客教程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值