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


少有人走的路



















