重构深层嵌套的方法主要有如下几种,主要来自《代码大全》。
1. 通过重复检测条件中的某一部分来简化嵌套的if语句
一个深层次嵌套的代码例子:
if(inputStatus == InputStatus_Success)
{
//lots of code
...;
if(printerRouting != NULL)
{
//lots of code
...;
if(SetupPage())
{
//lots of code
...;
if(AllocMem(&printData))
{
//lots of code
...;
}
}
}
}
利用重复测试可以修改为以下形式:
if( inputStatus == InputStatus_Success )
{
//lots of code
...;
if(printerRouting != NULL)
{
//lots of code
...;
}
}
if( (inputStatus == InputStatus_Success) &&
(printerRouting != NULL) && SetupPage() )
{
//lots of code
...;
if(AllocMem(&printData))
{
//lots of code
...;
}
}
这个例子表明不能无偿的减少嵌套层次;作为减少嵌套层次的代价,必须要容忍使用一个更复杂的判断。
2. 用break块来简化嵌套
上述例子采用break重构后:
do
{
if(inputStatus != InputStatus_Success)
break;
//lots of code
...;
if(printerRouting != NULL)
break;
//lots of code
...;
if(!SetupPage())
break;
//lots of code
...;
if(!AllocMem(&printData))
break;
//lots of code
...;
} while(false);
3. 把嵌套if转为case
4. 把深层次嵌套的代码抽取出来放进单独的子程序
5. 使用一种面向对象的方法:多态
对于各种规模的系统,都可以工厂模式来替换其中的swich case语句。
6. 用状态变量重写代码
enum Status
{
Status_Input_Fail,
Status_Print_Routing_NULL,
Status_Setup_Page_Fail,
Status_Alloc_Mem_Fail,
Status_Success
};
Status errorState = Status_Success;
if(inputStatus == InputStatus_Success)
{
//lots of code
...;
}
else
{
errorState = Status_Input_Fail;
}
if(errorState == Status_Success)
{
if(printerRouting != NULL)
{
//lots of code
...;
}
else
{
errorState = Status_Print_Routing_NULL;
}
}
if(errorState == Status_Success)
{
if(SetupPage())
{
//lots of code
...;
}
else
{
errorState = Status_Setup_Page_Fail;
}
}
if(errorState == Status_Success)
{
if(AllocMem(&printData))
{
//lots of code
...;
}
else
{
errorState = Status_Alloc_Mem_Fail;
}
}
优点:代码可读性要高些;
缺点:使用状态变量的方法应用还不够普遍,应该对它们的用法加以充分说明,否则有的人可能读不懂你的意图。
7. 用防卫子句来退出子程序,从而使代码的主要路径更为清晰
一个嵌套层次较深的字符串拷贝函数如下:
char * strcpy( char *strDest, const char *strSrc )
{
if(strDest != strSrc) //判断源目所指区域是否重叠
{
if( (strDest != NULL) && (strSrc != NULL) )
{
char *address = strDest;
while( (*strDest++ = * strSrc++) != '/0' );
return address;
}
else
{
return null;
}
}
else
{
return strDest;
}
}
采用防卫子句改写后:
char * strcpy( char *strDest, const char *strSrc )
{
if(strDest == strSrc)
{
return strDest;
}
if( (NULL == strDest) || (NULL == strSrc) )
{
return null;
}
char *address = strDest;
while( (*strDest++ = * strSrc++) != '/0' );
return address;
}
8. 使用异常
9. 完全重新设计深层嵌套的代码
大部分情况下,复杂的代码说明你还没有充分理解你的程序,所以无法简化它。所以深层嵌套是一个警告,它说明你要么分拆出一个子程序,要么应该重新设计程序。