这与beautiful code的章节有关。
在那一章中我读到了嵌套的if
s。
作者正在谈论深层嵌套的if
作为错误的创始人,而且可读性较差。
他正在谈论用if
语句和decision tables替换嵌套的case
。
任何人都可以说明如何使用if
(case
)和决策表删除嵌套的select case
吗?
答案 0 :(得分:21)
好吧,不是直接回答你的问题,因为你特别询问转换/案例陈述,但这是一个类似的问题。
Invert “if” statement to reduce nesting
这讨论了用guard-statements替换嵌套的if,它们提前返回,而不是在确定返回值之前逐步检查越来越多的东西。
答案 1 :(得分:10)
我总是尝试做的一个例子是更换嵌套如果是这样的(实际上这个不是太不好但是我已经看到它们在野外深达8或9级):< / p>
if (i == 1) {
// action 1
} else {
if (i == 2) {
// action 2
} else {
if (i == 3) {
// action 3
} else {
// action 4
}
}
}
用这个:
switch (i) {
case 1:
// action 1
break;
case 2:
// action 2
break;
case 3:
// action 3
break;
default:
// action 4
break;
}
我还尝试保持动作尽可能小(函数调用最好),以保持switch语句的压缩(所以你不必提前四页看到它的结尾)。
我认为,决策表只是设置标志,指示以后必须采取的行动。 “稍后”部分是基于这些标志的动作的简单排序。我可能是错的(它不会是第一次或最后一次: - )。
一个例子是(标志设置阶段可能很复杂,因为它的动作非常简单):
switch (i) {
case 1:
outmsg = "no paper";
genmsg = true;
mailmsg = true;
phonemsg = false;
break;
case 2:
outmsg = "no ink";
genmsg = true;
mailmsg = true;
phonemsg = false;
break;
default:
outmsg = "unknown problem";
genmsg = true;
mailmsg = true;
phonemsg = true;
break;
}
if (genmsg)
// Send message to screen.
if (mailmsg)
// Send message to operators email address.
if (phonemsg)
// Hassle operators mobile phone.
答案 2 :(得分:9)
链式ifs怎么样?
替换
if (condition1)
{
do1
}
else
{
if (condition2)
{
do2
}
else (condition3)
{
do3;
}
}
与
if (condition1) {
do1;
} else if (condition2) {
do2;
} else if (condition3) {
do3;
}
这很像复杂条件下的switch语句。
答案 3 :(得分:6)
将条件设置为布尔值,然后为每个案例编写布尔表达式。
如果代码是:
if (condition1)
{
do1
}
else
{
if (condition2)
{
do2
}
else (condition3)
{
do3;
}
}
可以将其写成:
bool cond1=condition1;
bool cond2=condition2;
bool cond3=condition3;
if (cond1) {do1;}
if (!cond1 and cond2) {do2;}
if (!cond1 and cond3) {do2;}
答案 4 :(得分:3)
对于决策表,请参阅我对this question的回答,或者最好还是阅读Code Complete 2中的第18章。
答案 5 :(得分:2)
例如,一旦部分验证失败,您就可以中断。
function validate(){
if(b=="" || b==null){
alert("Please enter your city");
return false;
}
if(a=="" || a==null){
alert("Please enter your address");
return false;
}
return true;
}
答案 6 :(得分:1)
决策表是将条件逻辑存储在数据结构中而不是代码本身的地方。
所以不要这样(使用@ Pax的例子):
if (i == 1) {
// action 1
} else {
if (i == 2) {
// action 2
} else {
if (i == 3) {
// action 3
} else {
// action 4
}
}
}
你做这样的事情:
void action1()
{
// action 1
}
void action2()
{
// action 2
}
void action3()
{
// action 3
}
void action4()
{
// action 4
}
#define NUM_ACTIONS 4
// Create array of function pointers for each allowed value of i
void (*actions[NUM_ACTIONS])() = { NULL, action1, action2, action3 }
// And now in the body of a function somewhere...
if ((i < NUM_ACTIONS) && actions[i])
actions[i]();
else
action4();
如果i
的可能性不是低编号整数,那么您可以创建一个查找表,而不是直接访问i
数组的actions
元素。
当你决定了几十个可能的值时,这种技术比嵌套的if
或switch
语句更有用。
答案 7 :(得分:0)
if和switch语句不是纯粹的OO。它们是有条件的程序逻辑,但是做得很好!如果您想删除这些语句以获得更多面向对象的方法,combine the 'State' and 'Descriptor' patterns。
答案 8 :(得分:0)
您也可以考虑使用Visitor pattern。
答案 9 :(得分:0)
嵌套if等效于逻辑运算符AND
if (condition1)
{
if (function(2))
{
if (condition3)
{
// do something
}
}
}
等效代码:
if (condition1 && function(2) && condition3)
{
// do something
}
在这两种情况下,当表达式求值为false时,将不会计算后续表达式。例如,如果condition1为false,则不会调用function(),也不会评估condition3。
答案 10 :(得分:-1)
某些语言允许的另一个例子是
switch true{
case i==0
//action
break
case j==2
//action
break
case i>j
//action
break
}