你如何处理巨大的条件?

Tei*_*ion 29 language-agnostic if-statement

这是我用过的每种语言都有问题的东西,我有一个if语句,但条件部分有很多检查,我必须将它分成多行,使用嵌套的if语句或只是接受它是丑陋的并继续前进用我的生命.

你找到的其他任何方法对我和其他遇到同样问题的人都有用吗?

示例,全部在一行:

if (var1 = true && var2 = true && var2 = true && var3 = true && var4 = true && var5 = true && var6 = true)
{
Run Code Online (Sandbox Code Playgroud)

例如,多行:

if (var1 = true && var2 = true && var2 = true
 && var3 = true && var4 = true && var5 = true
 && var6 = true)
{
Run Code Online (Sandbox Code Playgroud)

实施例嵌套:

if (var1 = true && var2 = true && var2 = true && var3 = true)
{
     if (var4 = true && var5 = true && var6 = true)
     {
Run Code Online (Sandbox Code Playgroud)

Coi*_*oin 61

在几个布尔值中分隔条件,然后使用主布尔值作为条件.

bool isOpaque = object.Alpha == 1.0f;
bool isDrawable = object.CanDraw && object.Layer == currentLayer;
bool isHidden = hideList.Find(object);

bool isVisible = isOpaque && isDrawable && ! isHidden;

if(isVisible)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

更好的是:

public bool IsVisible {
    get
    {
        bool isOpaque = object.Alpha == 1.0f;
        bool isDrawable = object.CanDraw && object.Layer == currentLayer;
        bool isHidden = hideList.Find(object);

        return isOpaque && isDrawable && ! isHidden;
    }
}

void Draw()
{
     if(IsVisible)
     {
         // ...
     }
}
Run Code Online (Sandbox Code Playgroud)

确保给出变量名称,指示意图而不是功能.这将极大地帮助开发人员维护您的代码...它可能就是您!


Kar*_*uin 12

我很惊讶没有人得到这个.有一种专门针对此类问题的重构:

http://www.refactoring.com/catalog/decomposeConditional.html

  • 我不喜欢Decompose Conditional,因为它使用不可重用的一次性函数来污染代码结构.我宁愿有一个大的IF声明,对每个相关检查的"组"都有评论. (3认同)

Sim*_*bee 7

这里有两个问题需要解决:可读性和可理解性

"可读性"解决方案是一种风格问题,因此可以解释.我的偏好是这样的:

if (var1 == true && // Explanation of the check
    var2 == true && // Explanation of the check
    var3 == true && // Explanation of the check
    var4 == true && // Explanation of the check
    var5 == true && // Explanation of the check
    var6 == true)   // Explanation of the check
    { }
Run Code Online (Sandbox Code Playgroud)

或这个:

if (var1 && // Explanation of the check
    var2 && // Explanation of the check
    var3 && // Explanation of the check
    var4 && // Explanation of the check
    var5 && // Explanation of the check
    var6)   // Explanation of the check
    { }
Run Code Online (Sandbox Code Playgroud)

也就是说,在扫描代码时,这种复杂的检查很难在心理上解析(特别是如果你不是原作者).考虑创建一个帮助方法来抽象出一些复杂性:

/// <Summary>
/// Tests whether all the conditions are appropriately met
/// </Summary>
private bool AreAllConditionsMet (
    bool var1,
    bool var2,
    bool var3,
    bool var4,
    bool var5,
    bool var6)
{
    return (
        var1 && // Explanation of the check
        var2 && // Explanation of the check
        var3 && // Explanation of the check
        var4 && // Explanation of the check
        var5 && // Explanation of the check
        var6);  // Explanation of the check
}

private void SomeMethod()
{
    // Do some stuff (including declare the required variables)
    if (AreAllConditionsMet (var1, var2, var3, var4, var5, var6))
    {
        // Do something
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,当视觉扫描"SomeMethod"方法时,隐藏了测试逻辑的实际复杂性,但保留了语义,以供人类在高级别理解.如果开发人员确实需要了解详细信息,则可以检查AreAllConditionsMet方法.

我认为这正式被称为"分解条件"重构模式.像Resharper或Refactor Pro这样的工具!可以轻松做这种重构!

在所有情况下,具有可读和可理解代码的关键是使用真实的变量名称.虽然我明白这是一个人为的例子,"VAR1","VAR2"等是可接受的变量名.它们的名称应该反映它们所代表的数据的基本性质.


Mik*_*ell 6

我经常将它们分成组件布尔变量:

bool orderValid = orderDate < DateTime.Now && orderStatus != Status.Canceled;
bool custValid = customerBalance == 0 && customerName != "Mike";
if (orderValid && custValid)
{
...
Run Code Online (Sandbox Code Playgroud)


aby*_*byx 5

首先,我将删除所有== true部分,使其缩短50%;)

当我有大的条件时,我会寻找原因.有时我看到我应该使用多态,有时我需要添加一些状态对象.基本上,它意味着需要重构(代码气味).

有时我使用De-Morgan定律来简化布尔表达式.