设计模式之策略模式(Strategy)

设计模式:面向对象语言开发过程中,对各种问题和场景的解决方案的沉淀 —是解决问题的套路,
提出场景–解决问题–总结沉淀–推广应用

行为型设计模式:关注对象和行为的分离
设计模式都是为了解决一类问题而存在的,往往在解决一类问题的同时会带来的新的问题,会有对应的解决方案。设计模式不是万能的。

策略模式定义

策略模式应对业务处理中,会有多种相似处理方式(算法),然后封装成算法+抽象,此外,调用环节也有扩展要求的,来个context
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
红色部分为稳定的,蓝色部门为变化的

代码实现

策略模式和简单工厂的结合
扩展性—抽象—反射—动态

    public interface ICaculation
    {
        int Caculation(int iInpuLeft, int iInputRight);
    }
    public class Devision : ICaculation
    {
        public int Caculation(int iInpuLeft, int iInputRight)
        {
            if (iInputRight == 0) throw new Exception();
            return iInpuLeft / iInputRight;
        }
    }

    public class Minus : ICaculation
    {
        public int Caculation(int iInpuLeft, int iInputRight)
        {
            return iInpuLeft - iInputRight;
        }
    }

    public class Mutiply : ICaculation
    {
        public int Caculation(int iInpuLeft, int iInputRight)
        {
            return iInpuLeft * iInputRight;
        }
    }

    public class Plus : ICaculation
    {
        public int Caculation(int iInpuLeft, int iInputRight)
        {
            return iInpuLeft + iInputRight;
        }
    }

定义Context上下文:

    /// <summary>
    /// 见过哪些context,---httpcontext dbcontext callcontext
    /// HttpContext,ControllerContext,ActionExecutingContext,ActionExecutedContext,ResultExecutingContext,ResulViewContexttExecutedContext,ExceptionContext,
    /// 上下文环境:是为了保存整个请求过程中,全部的信息--中间结果--最终结果
    /// 行为型设计模式的标配,行为会无止境的到处转移,方法需要参数。执行结果
    /// 包一层:没有什么技术问题是包一层不能解决的,如果有,再包一层
    /// 中间层,转移调用,核心意义就在于调用环节可以扩展
    /// </summary>
    public class CaculationContext
    {
        private ICaculation _iCaculation = null;
        private int _iInpuLeft = 0;
        private int _iInputRight = 0;
        public CaculationContext(ICaculation caculation, int iInpuLeft, int iInputRight)
        {
            this._iCaculation = caculation;
            this._iInpuLeft = iInpuLeft;
            this._iInputRight = iInputRight;
        }

        private string Para = "";//可能要调用第三方接口

        /// <summary>
        /// 也许调用算法,需要额外的参数信息
        /// </summary>
        /// <returns></returns>
        public int Action()
        {
            try
            {
                Console.WriteLine("Caculation");
                Console.WriteLine(this.Para);
                return this._iCaculation.Caculation(this._iInpuLeft, this._iInputRight);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }

        }
    }

定义工厂方法:

    /// <summary>
    /// 面向对象语言开发从来不担心代码多,因为可以封装一下
    /// 工厂只是转移了矛盾,并没有消除矛盾
    /// 代码的升级是一步一步来的,先升级再解决问题,先解决眼前的问题,再解决下一步的问题
    /// </summary>
    public class Factory
    {
        /// <summary>
        /// 不仅把对象创建给屏蔽了,而且映射关系也可以配置文件决定了
        /// </summary>
        /// <param name="operate"></param>
        /// <returns></returns>
        public static ICaculation GetCaculationReflection(string operate)
        {
            string key = $"ICaculation{operate}";
            string dllType = ConfigurationManager.AppSettings[key];
            Assembly assembly = Assembly.Load(dllType.Split(',')[1]);
            Type type = assembly.GetType(dllType.Split(',')[0]);
            return (ICaculation)Activator.CreateInstance(type);
        }
    }

调用方代码:

        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("下面是一个计算器展示demo:");
                while (true)
                {
                    Console.WriteLine("******************************");
                    Console.WriteLine("******************************");
                    Console.WriteLine("******************************");
                    #region UI 前端逻辑 接受用户输入并验证
                    int iInputLeft = 0;
                    int iInputRight = 0;
                    string operate = "";

                    Console.WriteLine("输入第一个数字(整数):");
                    string sInputLeft = Console.ReadLine();
                    if (!int.TryParse(sInputLeft, out iInputLeft))
                    {
                        Console.WriteLine("输入数字无效,请重新输入");
                        continue;
                    }

                    Console.WriteLine("输入计算符号(+-*/):");
                    operate = Console.ReadLine();
                    string CaculationType = System.Configuration.ConfigurationManager.AppSettings["CaculationType"];
                    if (!CaculationType.Split(',').Contains(operate))
                    {
                        Console.WriteLine("输入计算符号无效,请重新输入");
                        continue;
                    }

                    Console.WriteLine("输入第二个数字(整数):");
                    string sInputRight = Console.ReadLine();
                    if (!int.TryParse(sInputRight, out iInputRight))
                    {
                        Console.WriteLine("输入数字无效,请重新输入");
                        continue;
                    }
                    #endregion

                    #region 后台逻辑 业务逻辑
                    int iResult = 0;
                    //1 转移了算法逻辑
                    ICaculation iCaculation = Factory.GetCaculationReflection(operate);
                    CaculationContext context = new CaculationContext(iCaculation, iInputLeft, iInputRight);
                    
                    //2 转移了算法的调用逻辑
                    iResult = context.Action();
                    
                    Console.WriteLine("计算为: {0}{1}{2}={3}", iInputLeft, operate, iInputRight, iResult);
                    #endregion
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }

配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <appSettings>
    <add key="ICaculation-" value="StrategyPattern.Service.Plus,StrategyPattern.Service"/>
    <add key="ICaculation+" value="StrategyPattern.Service.Minus,StrategyPattern.Service"/>
    <add key="ICaculation*" value="StrategyPattern.Service.Mutiply,StrategyPattern.Service"/>
    <add key="ICaculation/" value="StrategyPattern.Service.Devision,StrategyPattern.Service"/>
    <add key="CaculationType" value="+,-,*,/,%"/>
  </appSettings>
</configuration>

要点总结

好处:算法封装,有抽象可以扩展;调用环节转移,可以扩展;
在这里插入图片描述
在代码中看到if…else…,并且其在未来是变化的,就应该考虑是否可以采用Strategy模式!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值