我参与了一个涉及复杂布尔逻辑的项目。这种复杂性使代码非常有效,但遗憾的是难以阅读。
因此,我们将逻辑排除在下面,这使得更容易在复合语句中查看组,并且还可以向逻辑的某些部分添加注释。
(此代码不是来自项目的真实代码,真正的逻辑更复杂)
if (
//comments here!
angle.angle < kQuiteLow
&& (
previousAngle.angle > kQuiteHigh
|| previousAngle.time == kUnknownTime
)
//comments in here too!
&& pairedAngle.angle < kQuiteLow
&& (
//and here
previousPairedAngle.angle > kQuiteHigh
|| previousPairedAngle.time == kUnknownTime
)
)
你有没有在其他任何地方看到过这种情况?
是否有关于如何布置非常复杂的布尔逻辑的约定或样式指南?
答案 0 :(得分:7)
我会重构代码以使用外部方法使其更容易阅读。
if( ValidAngle(angle, previousAngle) && ValidAngle(pairedAngle, previousPairedAngle) )
ValidAngle( angle, prevAngle){
return angle.angle < kQuiteLow && (previousAngle.angle > kQuiteHigh || previousAngle.time == kUnknownTime)
}
答案 1 :(得分:1)
一个建议是将逻辑分解为方法。更容易将您的注释转换为方法名称,因此您不需要它们。或者,如果它们太复杂,它们将包含在方法文档中。
if (anglesAreOk(...))
{
}
public bool analyseAngles() {
return angleOk(...) && previousAngleOk(...) && pairedAngleOk(...)
}
你想到了......
答案 2 :(得分:0)
我同意samuelcarrijo和pb,将复杂的表达式提取到方法或变量中。
如果无法将方法提取为有意义的抽象,则可以考虑code fragments or blocks。
答案 3 :(得分:0)
从Fowler的重构书中,我同意复杂的布尔逻辑应该被具有有意义名称的方法所取代的建议,例如。
if(x && y || !b) { }
VS
if(customerIsRepeatCustomerFromIdaho(x,y,b)){ }
或各种有意义名称的单元测试
e.g。
[Test]
public void CustomersFromIdahoGetDiscountsOnAlternatingTuesdays()
{
isRepeat=true;isFromIdaho=false;isTuesday=true;
Assert.AreEqual(Customer.CalclateDiscount(isRepeat,isFromIdaho,isTuesday),.10)
}
答案 4 :(得分:0)
如何为您的课程添加限制?
e.g。
if ( angle.isQuiteLow() && previousAngle.isQuiteHigh() && previousAngle.isUnknownTime() )