如何重构多重判断if-else最近改别人的代码,看到以前他写得太烂了,有很多if-else判断,于是想重构。大家看有
如何重构多重判断if-else 最近改别人的代码,看到以前他写得太烂了,有很多if-else判断,于是想重构。大家看有没有什么好的方法? 以前的代码是这么写的(例子):
UserProp m_Prop; ////////////////////////////////////// if ( m_Prop.A == 1 ) { if ( m_Prop.B == 1 ) { return "Good"; } else if ( m_Prop.B == 2 ) { return "Not too bad"; } else return "Just so so"; } else if ( m_Prop.A == 2 ) { if ( m_Prop.B == 1 ) { if ( m_Prop.C == 1 ) { return "Need improvement"; } else return "Need more improvement"; } else if ( m_Prop.B == 2 ) { return "Have a chance to improve"; } else return "Too bad"; } [解决办法] 这不一定能重构。你的那些state有多少个态?
[解决办法] 这样的if-else还好啦,而且及时return,效率并不低。
引用: 最近改别人的代码,看到以前他写得太烂了,有很多if-else判断,于是想重构。大家看有没有什么好的方法? 以前的代码是这么写的(例子):UserProp m_Prop; ////////////////////////////////////// if ( m_Prop.A == 1 ) { if ( m_Prop.B == 1 ) { return "Good"; } else if ( m_Prop.B == 2 ) { return "Not too bad"; } else return "Just so so"; } else if ( m_Prop.A == 2 ) { if ( m_Prop.B == 1 ) { if ( m_Prop.C == 1 ) { return "Need improvement"; } else return "Need more improvement"; } else if ( m_Prop.B == 2 ) { return "Have a chance to improve"; } else return "Too bad"; } [解决办法] 整体来说,没有太好的办法。其实这个代码还是比较容易读懂的。具体到这个例子,我以为可以这样写,当然未见得更易懂:
UserProp m_Prop; ////////////////////////////////////// ASSERT( (unsigned)(m_Prop.A-1) < 2 ); const char * prompts[]={"Good","Not too bad", "Just so so", ”Need more improvement", "Have a chance to improve", "Too bad"}; int tmp=unsigned(m_Prop.B-1); int i=(m_Prop.A-1)*3+ tmp>1?2:tmp; return i==3&&m_Prop.C==1 ? "Need improvement" : prompts[i]; 两者(应该)功能上等效。但从易读懂,易维护的角度来看,原版应该更好。比如,如果m_Prop.B要细分为4类时,上面的代码就要大修。想使用这种"聪明"的办法,又要避免未预期的变化以难以追踪的方式break这些code,可以多放一些ASSERT,比如上面可以ASSERT( (unsigned)(m_Prop.B-1) <3 ); // 根据当前设计,只允许1,2,3三种值,那么上面的实现代码还可以进一步简化为:
UserProp m_Prop; ////////////////////////////////////// ASSERT( (unsigned)(m_Prop.A-1) < 2 ); ASSERT( (unsigned)(m_Prop.B-1) < 3 ); const char * prompts[]={"Good","Not too bad", "Just so so", ”Need more improvement", "Have a chance to improve", "Too bad"}; int i=(m_Prop.A-1)*3+ m_Prop.B-1; return i==3&&m_Prop.C==1 ? "Need improvement" : prompts[i];
Not necessarily better/smarter, just different.
[解决办法] 这种应该可以满足你的需求吧
引用: //这样呢? int state = (m_Prop.A << 8) [解决办法] (m_Prop.B << 4) [解决办法] m_Prop.C; switch(state){ } //或者搞几个mask?[解决办法] 我觉得原版写的很清楚
在执行效率相同的情况下,逻辑清楚功能分明的100行要比代码复杂技巧高明的10行更好
[解决办法] 引用: 最近改别人的代码,看到以前他写得太烂了,有很多if-else判断,于是想重构。大家看有没有什么好的方法? 以前的代码是这么写的(例子):UserProp m_Prop; ////////////////////////////////////// if ( m_Prop.A == 1 ) { if ( m_Prop.B == 1 ) { return "Good"; } else if ( m_Prop.B == 2 ) { return "Not too bad"; } else return "Just so so"; } else if ( m_Prop.A == 2 ) { if ( m_Prop.B == 1 ) { if ( m_Prop.C == 1 ) { return "Need improvement"; } else return "Need more improvement"; } else if ( m_Prop.B == 2 ) { return "Have a chance to improve"; } else return "Too bad"; } 重构不是盲目进行的,也就是说,代码本身不能狗说明长成什么样子就对了,即,代码要实现的功能是什么。只有从本质上清楚我们要解决的问题域,才能使我们设计出更好的代码结构。
一般来说,去掉if可以用switch替换,去掉switch可以用数组或者面向对象的多态来替换。
如果你能从问题域角度出发,能够抽象出多个分类,可以使用多态来解决。如果是同一事物在不同状态下有不同的行为,你可以使用状态模式来解决。
[解决办法] 其实我们做项目时首先注意的是软件的整体架构,然后是某个模块的架构,再就是到类的设计等等。当然怎样设计好的架构,有很多书籍都有说到,基本上不外乎易于理解,维护,扩展之类的。需要说明的是不要为了达到所谓的这些要求,然后进行无限制的设计。 不管当初这些架构设计的怎样,随着项目的进行,总是有这有那前面没想到问题,其中有些问题需要我们对于现在的架构/类/函数进行改进,否则没办法进行,这个时候需要重构,当然重构可大可小,大到软件整体架构,小到类/函数的重新设计/实现。
在C++中,理论上我们应减少像if/else的使用,但是单从你给定的代码来说,没办法给你一个很好的重构方案,如果仅是想换成像switch的代码,我觉得大可没有必要,除非它影响到外面(或者客户)的使用,或者你需要加入新的功能,这样的代码使你很难理解或者扩展,那你可以尝试重构一下,如果是关乎模块的设计,可以了解些design pattern。但是不管怎样,把UserProp.A/B/C改成enum类型是一个比较好的习惯,至少让人好理解。
[解决办法] UserProp m_Prop; ////////////////////////////////////// //如果m_Prop.B的取值范围在1~9之间 int AB=m_Prop.A*10+m_Prop.B; switch (AB) { case 11: return "Good"; case 12: return "Not too bad"; case 21: if (m_Prop.C==1) return "Need improvement"; else return "Need more improvement"; case 22: return "Have a chance to improve"; default: if (AB<=19) return "Just so so"; else return "Too bad"; } http://bbs.csdn.net/topics/380157851