策略模式+函数映射实现去掉几千个case语句

勇哥注:

需求是,一个服务端的进程,通过外部进程传入的字符串,执行对应的运动卡的api。
因为不同运动卡的api加上一起,会有数千个if或者case语句进行判断。
我们怎么去掉这上千个判断语句呢?



下面是使用策略模式实现的效果:

因为api原型都是返回值为int,函数参数中的数量是不一样的。

勇哥这里按参数数量不同来包装成不同的策略。

这样处理后runAPI的几个子类中的case语句还是必须有的。

另外,策略模式中那个Context类,其实就是就是那个exec函数做的事。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication23
{
    public enum dmcAPIEnum
    {
        funA1, funA2, funB1, funB2, funC1,funC2
    }

    class Program
    {

        static void Main(string[] args)
        {

            List<object> para1List = new List<object>();
            para1List.Add(1);
            List<ApiParamType> cmdlist = new List<ApiParamType>();
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funB1, ParamList = para1List });
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funB2, ParamList = para1List });


            List<object> para2List = new List<object>();
            para2List.Add(1); para2List.Add(1);
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funA1, ParamList = para2List });
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funA2, ParamList = para2List });

            List<object> para4List = new List<object>();
            para4List.Add(1); para4List.Add(1); para4List.Add(1.0); para4List.Add(2.0);
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funC1, ParamList = para4List });
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funC2, ParamList = para4List });


            exec(cmdlist);

            Console.ReadKey();
        }

        static void exec(List<ApiParamType> cmdlist)
        {
            foreach (var m in cmdlist)
            {
                RunAPI api = null;
               
                switch (m.ParamList.Count)
                {
                    case 1:
                        api = new oneParam();
                        break;
                    case 2:
                        api = new twoParam();
                        break;
                    case 4:
                        api = new fourParam();
                        break;
                }
                api.Run(m.APIName, m.ParamList);
            }

        }

    }

    public abstract class RunAPI
    {
        public abstract int Run(dmcAPIEnum cmdname,List<object> data);
    }

    public class oneParam : RunAPI
    {
        dmcSdk dmc = new dmcSdk();
        int res = -1;
        public override int Run(dmcAPIEnum cmdname, List<object> data)
        {
            switch(cmdname)
            {
                case dmcAPIEnum.funB1:
                    res = dmc.funB1(((int)data[0]));
                    break;
                case dmcAPIEnum.funB2:
                    res = dmc.funB2(((int)data[0]));
                    break;
            }
            return res;
        }
    }

    public class twoParam : RunAPI
    {
        dmcSdk dmc = new dmcSdk();
        int res = -1;
        public override int Run(dmcAPIEnum cmdname, List<object> data)
        {
            switch (cmdname)
            {
                case dmcAPIEnum.funA1:
                    res = dmc.funA1(((int)data[0]), ((int)data[1]));
                    break;
                case dmcAPIEnum.funA2:
                    res = dmc.funA2(((int)data[0]), ((int)data[1]));
                    break;
            }
            return res;
        }
    }


    public class fourParam : RunAPI
    {
        dmcSdk dmc = new dmcSdk();
        int res = -1;
        public override int Run(dmcAPIEnum cmdname, List<object> data)
        {
            switch (cmdname)
            {
                case dmcAPIEnum.funC1:
                    res = dmc.funC1(((int)data[0]), ((int)data[1]), ((double)data[2]), ((double)data[3]));
                    break;
                case dmcAPIEnum.funC2:
                    res = dmc.funC2(((int)data[0]), ((int)data[1]), ((double)data[2]), ((double)data[3]));
                    break;
            }
            return res;
        }
    }



    public class ApiParamType
    {
        public dmcAPIEnum APIName { get; set; }

        public List<object> ParamList { get; set; }
    }

    public class dmcSdk
    {
        public int funA1(int cardno, int axisid)
        {
            Console.WriteLine($"funA1()");
            return 0;
        }

        public int funA2(int cardno, int axisid)
        {
            Console.WriteLine($"funA2()");
            return 0;
        }

        public int funB1(int cardno)
        {
            Console.WriteLine($"funB1()");
            return 0;
        }

        public int funB2(int cardno)
        {
            Console.WriteLine($"funB1()");
            return 0;
        }

        public int funC1(int cardno,int axisid,double minspeed,double maxspeed)
        {
            Console.WriteLine($"funC1()");
            return 0;
        }

        public int funC2(int cardno, int axisid, double minspeed, double maxspeed)
        {
            Console.WriteLine($"funC2()");
            return 0;
        }

    }

}


继续优化。。。。


下面是使用策略模式+函数映射改造后结果:

可以看到我们把几个runAPI的子类中的case语句干掉了!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication23
{
    public enum dmcAPIEnum
    {
        funA1, funA2, funB1, funB2, funC1,funC2
    }

    class Program
    {

        static void Main(string[] args)
        {

            List<object> para1List = new List<object>();
            para1List.Add(1);
            List<ApiParamType> cmdlist = new List<ApiParamType>();
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funB1, ParamList = para1List });
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funB2, ParamList = para1List });


            List<object> para2List = new List<object>();
            para2List.Add(1); para2List.Add(1);
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funA1, ParamList = para2List });
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funA2, ParamList = para2List });

            List<object> para4List = new List<object>();
            para4List.Add(1); para4List.Add(1); para4List.Add(1.0); para4List.Add(2.0);
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funC1, ParamList = para4List });
            cmdlist.Add(new ApiParamType() { APIName = dmcAPIEnum.funC2, ParamList = para4List });


            exec(cmdlist);

            Console.ReadKey();
        }

        static void exec(List<ApiParamType> cmdlist)
        {
            foreach (var m in cmdlist)
            {
                RunAPI api = null;
               
                switch (m.ParamList.Count)
                {
                    case 1:
                        api = new oneParam();
                        break;
                    case 2:
                        api = new twoParam();
                        break;
                    case 4:
                        api = new fourParam();
                        break;
                }
                api.Run(m.APIName, m.ParamList);
            }

        }

    }

    public abstract class RunAPI
    {
        internal dmcSdk dmc = new dmcSdk();
        public Dictionary<dmcAPIEnum, Func<int,int>> oneParamFunc = new Dictionary<dmcAPIEnum, Func<int,int>>();
        public Dictionary<dmcAPIEnum, Func<int,int, int>> twoParamFunc = new Dictionary<dmcAPIEnum, Func<int,int, int>>();
        public Dictionary<dmcAPIEnum, Func<int, int,double,double, int>> fourParamFunc = new Dictionary<dmcAPIEnum, Func<int, int,double,double, int>>();

        public RunAPI()
        {
            oneParamFunc.Add(dmcAPIEnum.funB1, dmc.funB1);
            oneParamFunc.Add(dmcAPIEnum.funB2, dmc.funB2);

            twoParamFunc.Add(dmcAPIEnum.funA1, dmc.funA1);
            twoParamFunc.Add(dmcAPIEnum.funA2, dmc.funA2);

            fourParamFunc.Add(dmcAPIEnum.funC1, dmc.funC1);
            fourParamFunc.Add(dmcAPIEnum.funC2, dmc.funC2);
        }

        public abstract int Run(dmcAPIEnum cmdname,List<object> data);
    }


    public class oneParam : RunAPI
    {
        public override int Run(dmcAPIEnum cmdname, List<object> data)
        {
            return base.oneParamFunc[cmdname].Invoke(((int)data[0])); ;
        }
    }

    public class twoParam : RunAPI
    {
        public override int Run(dmcAPIEnum cmdname, List<object> data)
        {
            return base.twoParamFunc[cmdname].Invoke(((int)data[0]), ((int)data[1])); ;
        }
    }


    public class fourParam : RunAPI
    {
        public override int Run(dmcAPIEnum cmdname, List<object> data)
        {
            return base.fourParamFunc[cmdname].Invoke(((int)data[0]), ((int)data[1]), ((double)data[2]), ((double)data[3])); ;
        }
    }



    public class ApiParamType
    {
        public dmcAPIEnum APIName { get; set; }

        public List<object> ParamList { get; set; }
    }

    public class dmcSdk
    {
        public int funA1(int cardno, int axisid)
        {
            Console.WriteLine($"funA1()");
            return 0;
        }

        public int funA2(int cardno, int axisid)
        {
            Console.WriteLine($"funA2()");
            return 0;
        }

        public int funB1(int cardno)
        {
            Console.WriteLine($"funB1()");
            return 0;
        }

        public int funB2(int cardno)
        {
            Console.WriteLine($"funB1()");
            return 0;
        }

        public int funC1(int cardno,int axisid,double minspeed,double maxspeed)
        {
            Console.WriteLine($"funC1()");
            return 0;
        }

        public int funC2(int cardno, int axisid, double minspeed, double maxspeed)
        {
            Console.WriteLine($"funC2()");
            return 0;
        }

    }

}




--------------------- 

作者:hackpig

来源:www.skcircle.com

版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2023-12-07 14:31:16 编辑

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864