勇哥注:
需求是,一个服务端的进程,通过外部进程传入的字符串,执行对应的运动卡的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
版权声明:本文为博主原创文章,转载请附上博文链接!

