大佬教程收集整理的这篇文章主要介绍了c – DRY if语句,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
if (!thing1.empty() && !thing2.empty()) { if (thing1.property < thing2.property) return func1(); else if (thing2.property < thing1.property) return func2(); else return func3(); } else if (!thing1.empty()) { return func1(); } else if (!thing2.empty()) { return func2(); } else { return func4(); }
如果thing1大于thing2,我试图以某种方式执行func,如果情况相反,我会尝试向后执行func,但如果不存在那么我只会为那一半执行func.如果两者都不存在,我会做一些完全不同的事情.每次使用此模式时,属性,函数和返回类型都不同.对于我想做的事情有没有比这个丑陋的嵌套if语句更好的设计?
编辑:实现我的示例代码过于简单化.这里有一些我真正的代码,希望能更好地解释这个问题(虽然它更麻烦):
if (!diamondsOnly.empty() && !clubsOnly.empty()) { if (diamondsOnly.size() < clubsOnly.size()) { if (passHighCards(player.hand,getHighCards(Card::DIAMONDS),result)) return result; if (passHighCards(player.hand,getHighCards(Card::CLUBS),result)) return result; } else if (clubsOnly.size() < diamondsOnly.size()) { if (passHighCards(player.hand,result)) return result; } else { if (diamondsOnly.BACk().value > clubsOnly.BACk().value) { if (passHighCards(player.hand,result)) return result; if (passHighCards(player.hand,result)) return result; } else { if (passHighCards(player.hand,result)) return result; } } } else if (!diamondsOnly.empty()) { if (passHighCards(player.hand,result)) return result; } else if (!clubsOnly.empty()) { if (passHighCards(player.hand,result)) return result; }
看一下真正的代码,我注意到的第一件事就是有很多几乎相同的调用只有一个常数变化.我会使用在复杂逻辑中设置的参数在一个地方进行调用.
// Decide what to do. std::vector<Card::Suit> passOrder; if (!diamondsOnly.empty() && !clubsOnly.empty()) { // .. complicated logic that adds suits to passOrder .. } // Do it. for (auto suit : passOrder) { // This is C++11 style -- alter as needed if (passHighCards(player.hand,getHighCards(suit),result)) return result; }
(如果它总是只有一个或两个,使用向量可能是过度的,但我假设真正的代码可能会处理所有的诉讼.)
这使得阅读更容易.程序员可以看到,首先你决定通过卡的顺序,然后你实际上是通过它们.两个单独的步骤将更加清晰.只有一个调用passCards的地方使得它更容易产生愚蠢的拼写错误,而不是让它的副本分散在整个决策逻辑中.它也会使调试变得更容易,因为您可以在非常特定的情况下设置断点,或者您可以在循环开始时设置断点并检查passOrder.
简化逻辑
接下来我们想简化决策逻辑.
选项:
> SenTinels:复杂的部分原因在于,在某些情况下,您需要取消引用其中一个容器中的最后一张卡,如果容器为空,则无法取消.有时候值得考虑在容器中添加一个标记,这样你就不需要测试空壳了 – 你可以保证它永远不会空着.这可能是可行的,也可能是不可行的.您需要使处理容器的所有其他代码了解哨兵.
>只是例外:你可以通过选择默认订单来消除一些条款,例如,钻石然后是球杆,然后只测试你需要球杆然后钻石的情况.
>使用Temporaries进行表达:创建名称极佳的临时工具,简化您必须进行的比较,并根据这些临时表达比较.请注意,如果将空/非空案例分解为临时案例,则可以通过选择适当的SENTinEL_VALUE(如0或-1)来消除某些情况.
把它们放在一起:
// For readability. const bool fewerClubs = clubsOnly.size() < diamondsOnly.size(); const bool samenumber = clubsOnly.size() == diamondsOnly.size(); const int lastDiamondValue = diamondsOnly.empty() ? -1 : diamondsOnly.BACk().value; const int lastClubValue = clubsOnly .empty() ? -1 : clubsOnly .BACk().value; // Decide what order to SELEct cards for passing. std::vector<Card::Suit> passOrder; passOrder.push_BACk(Cards::DIAMONDS); // default order passOrder.push_BACk(Cards::CLUBS); // Do we need to change the order? if (fewerClubs || (samenumber && lastClubValue > lastDiamondvalue)) { // Yep,so start with the clubs instead. passOrder[0] = Cards::CLUBS; passOrder[1] = Cards::DIAMONDS; } // Do it. for (auto suit : passOrder) { // This is C++11 style -- alter as needed if (passHighCards(player.hand,result)) return result; }
这假设getHighCards处理可能为空的容器作为输入.
以上是大佬教程为你收集整理的c – DRY if语句全部内容,希望文章能够帮你解决c – DRY if语句所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。