我有一个巨大的开关案例,里面有嵌套的switch case语句,我想知道是否有人对如何清理有任何想法?
switch (datatype) {
case STR:
{
switch(operation)
{
case EQUALS:
{
/* perform str compare */
}
case NOTEQUALS:
{
}
case LT:
{
}
case GT:
{
}
case GTE:
{
}
case LTE:
{
}
default:
break;
}
break;
}
case VER:
{
switch(operation)
{
case EQUALS:
{
/* perform version compare */
}
case NOTEQUALS:
{
}
case LT:
{
}
case GT:
{
}
case GTE:
{
}
case LTE:
{
}
default:
break;
}
break;
}
case INT:
{
/* same */
}
case FLOAT:
{
/* same */
}
/* ... more types ... */
/* ... .......... ... */
default:
break;
}
答案 0 :(得分:11)
如果操作的值是连续的,则可以创建一个函数指针表。实际上,您可以创建一个包含单独函数的函数指针的2D表来处理每个操作/类型组合。 e.g
// do some range checking on input params
// invoke the handler
handlers[datatype][operation]();
答案 1 :(得分:5)
创建一些表(数组),其中包含指向函数的指针。然后,您可以查找func[STR][EQUALS]
以进行适当的呼叫。电话会看起来像这样......
Func[datatype][operation]();
答案 2 :(得分:2)
您可以尝试the command pattern。
答案 3 :(得分:2)
NOTEQUALS
案件总是可以用EQUALS
案件来写;就GTE
而言,LT
和LTE
方面的GE
类似。因此,根据operation
进行外部切换,这六种情况中只有三种需要打开datatype
。
答案 4 :(得分:0)
你可以使用大量的函数指针,然后根据索引到数组中正确的函数指针来调用相关的函数。
答案 5 :(得分:0)
您是否创造性地考虑使用一系列函数指针并将它们存储在结构中?
做得对,您可以模仿对象并执行以下操作:
bool someArbitraryFunction (dataType aDatatype, operations anOperation)
{
someUnknownStruct.datatype = aDatatype;
someUnknownStruct.operation = anOperation;
return someUnknownStruct->doMath(1,2);
}
然后你可以将所有必需的数学函数,枚举和结构放在某个头文件中。
清理代码的“肉”,并使数学可移植(只需将其导入到您需要的任何地方)。
答案 6 :(得分:0)
假设你的案例都可以返回一个简单的布尔值,所有六个逻辑案例都可以用LT和EQUALS重写,如下所示:
switch(operation) {
case EQUALS:
return isEquals();
case NOTEQUALS:
return !isEquals();
case LT:
return isLT();
case GT:
return !isLT() && !isEquals();
case GTE:
return !isLT();
case LTE:
reutrn isLT() || isEquals();
default:
break;
}
这只需要你编写isLT()和isEquals()的逻辑,这将在必要时进行数据类型的切换。这消除了大量不必要的代码重复,但不会牺牲很多易读性。
这可以与Stephen Doyle和rikh已经建议的函数指针结合使用,这将彻底消除switch()语句。