我可以避免使用太多“if - else if”在下面的示例中? [英] Can I avoid using too many "if - else if" in the sample below?

查看:89
本文介绍了我可以避免使用太多“if - else if”在下面的示例中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

if (length >= 24 && Acct == strAcct && code == strCode1)
            {
                if (Box.HasValues)
                {
                    if (alk.Count > 1)
                    {
                        if (Effect != strReceive && strVal == "A")
                        {
                            Method1();
                        }
                        else
                        {
                            Method2();
                        }
                    }
                    else
                    {
                        Method2();
                    }
                }
            }
            else if (length >= 24 && Acct == strAcct && code == strCode2)
            {
                if (Box.HasValues)
                {
                    Method3();
                }
            }







第一个if和else if if difference是strCode1& strCode2。

有没有办法让我避免if -else if。

我想做一点简短并用新的操作符更新!




For the first if and else if only difference is strCode1 & strCode2.
Is there any way I make this avoiding if -else if.
I want to make this little short and updated with new Operators maybe!

推荐答案

那么,在这种情况下,删除重复条件非常容易......

Well, in that case, it is very easy to remove duplicate conditions...
if (length >= 24 && Acct == strAcct && Box.HasValues)
{
    if (code == strCode1)
    {
        if (alk.Count > 1 && Effect != strReceive && strVal = "A")
        {
            Method1();
        }
        else
        {
            Method2();
        }
    }
    else if (code == strCode2)
    {
        Method3();
    }
}



您可能决定使用开关案例来测试代码(如果您比较的字符串是常量)。如果您要测试的代码超过2个,这将非常有用。



此外,您可以使用三元运算符作为内部条件。

正如有人在评论中指出的那样,在C#中,在这种情况下不起作用。仅当两个函数都返回兼容类型并分配结果时,它才有效。在C ++中没有这样的限制。



虽然,你也可以将它用于外部条件,有时候if,switch和?的适当组合:可以帮助使代码更容易阅读。



适当的行拆分也有助于使代码更易于阅读。通常对于具有多个条件的if,我会在每个&&。之后断开线。


You might decide to use a switch case to test the code (if the string you compare to are constants). This would be useful if you have more than 2 code to test.

Also, you can use ternary operator for the inner condition.
As someone pointed out in comments, in C#, that won't work in that case. It would works only if both function returns compatible type and the result is assigned. In C++ there are no such restriction.

Although, you might also use it for outer conditions, sometime an appropriate mix of if, switch and ?: can help make the code easier to read.

Appropriate split of line can also help make the code easier to read. Often for an if with multiple condition, I would break the line after each &&.

// In C#, constant string can be used for switch cases. 
// If string are not constant, then one would have to use previous example code...
const string strCode1 = "code1";
const string strCode2 = "code2";

if (length >= 24 && Acct == strAcct && Box.HasValues)
{
    switch (code)
    {
        case strCode1:
            // As pointed out in comments, this won't work in C# (it does in C++).
            alk.Count > 1 && Effect != strReceive && strVal = "A" ? 
                Method1() : 
                Method2();
            // Replace instead by code from previous example.
            break;

        case strCode2:
            Method3();
            break;
    }
}


减少复杂的嵌套如果 s和 else s不是一项简单的任务。这是一个典型的重构任务,首先需要一个良好的单元测试覆盖率。



现在,如何系统地解决这个问题?



1。没有重组,但将常用术语合并到函数中



我建议首先不要改变结构,而是通过将常见的精细条件组合到谓词函数中来简化。在您的情况下(假设以大写字母开头的名称是该类的成员),转换
Reducing complex nested ifs and elses is not a trivial task. This is a typical refactoring task which first of all calls for a good unit test coverage.

Now, how to tackle the problem in a systematic manner?

1. No restructuring but combine common terms into functions

I suggest to first not change the structure but simplify by combining common elaborate conditions into predicate functions. In your case (assuming names starting on capital letters are members of the class), convert
if (length >= 24 && Acct == strAcct && ...
...
else if (length >= 24 && Acct == strAcct && ...

进入

bool IsAcct(int length, string strAcct)
{
    return length >= 24 && Acct == strAcct;
}
...
if (IsAcct(length, strAcct) && ...
...
else if (IsAcct(length, strAcct) && ...

同样转换

if (Effect != strReceive && strVal == "A") ...

进入

bool IsDesiredEffect(string strReceive, string strVal)
{
    return Effect != strReceive && strVal == "A";
}
...
if (IsDesiredEffect(strReceive, strVal)) ...



2。列出每个代码分支的所有条件



最好先给每个简单条件一个代码,例如


2. List all conditions for each code branch

This is best done by first give each simple condition a code, e.g.

// A: IsAcct(length, strAct)
// C: code == strCode1
// D: Box.HasValues
// E: alk.Count > 1
// F: IsDesiredEffect(strRecieve, strVal)
// G: code == strCode2

装饰代码如下所示

if (IsAcct(length, strAcct) && code == strCode1)         // A && C
{
    if (Box.HasValues)                                   // A && C && D
    {
        if (alk.Count > 1)                               // A && C && D && E
        {
            if (IsDesiredEffect(strReceive, strVal))     // A && C && D && E && F
            {
                Method1();
            }
            else                                         // A && C && D && E && !F
            {
                Method2();
            }
        }
        else                                             // A && C && D && !E
        {
            Method2();
        }
    }
}
else if (IsAcct(length, strAcct) && code == strCode2)    // A && !C && G
{
    if (Box.HasValues)                                   // A && !C && G && D
    {
        Method3();
    }
}

这导致方法的以下条件

Method1() //  A && C && D && E && F
Method2() //  A && C && D && E && !F  || A && C && D && !E
Method3() //  A && !C && G && D





3。重新安排和简化表达式



在这里你需要了解布尔逻辑转换的基础知识。



3. Re-arrange and simplify expressions

Here you need to know basics of Boolean logic transformations.

Method1() //    A && D && C && E && F
Method2() //    A && D && C && E && !F || A && D && C && !E
          // => A && D && C && (E && !F || !E)
          // => A && D && C && (!E || !F)
          // => A && D && C && !(E && F)
Method3() //    A && D && !C && G

整洁:

Method1() //    A && D &&  C &&   E && F
Method2() //    A && D &&  C && !(E && F)
Method3() //    A && D && !C &&  G





4。再次组合常用表达式



例如



4. Combining common expressions again

E.g.

Method1() //    AD &&  C &&  EF
Method2() //    AD &&  C && !EF
Method3() //    AD && !C &&  G

相应地扩展谓词:

// AD: IsAcct(length, strAct)
// C: code == strCode1
// EF: IsDesiredEffect(alk, strRecieve, strVal)
// G: code == strCode2
...
bool IsAcct(int length, string strAcct)
{
    return length >= 24 && Acct == strAcct && Box.HasValue;
}
bool IsDesiredEffect(ICollection alk, string strReceive, string strVal)
{
    return alk.Count > 1 && Effect != strReceive && strVal == "A";
}





5。最后组成简化版本



5. Finally composing the reduced version

if (IsAcct(length, strAct))
{
    if (code == strCode1)
    {
        if (IsDesiredEffect(alk, strReceive, strVal))
        {
            Method1();
        }
        else
        {
            Method2();
        }
    }
    else if (code == strCode2)
    {
        Method3();
    }
}





摘要



我同意,这种做法看起来有点压倒性。但它为您提供了这种复杂转型的系统方法。使用表达式(A,C,D等)的代码的方法允许更容易地处理布尔表达式变换。它还有助于同行评审/配对编程,让精简逻辑进行讨论,而不是让代码细节混乱。



Don在重构决策树之前,不要忘记从一系列良好的单元测试开始!



玩得开心!

干杯

Andi



Summary

This approach might look a bit overwhelming, I agree. But it provides you with a systematic approach for such complex transformation. The approach with the codes for the expressions (A, C, D, etc.) allows for easier dealing with the Boolean expression transformations. It also helps in a peer review/pair programming to have the condensed logic to discuss rather than having the logic cluttered with code details.

Don't forget to start with a good set of unit tests before refactoring decision trees!

Have fun!
Cheers
Andi


说明另一种重新分解的方法:



a。分析可以跳过分析的情况:



如果(长度<24)返回;

if(Acct!= strAcct)返回;

if(!Box.HasValues)返回;



b。将它们组合成短路OR:
To illustrate another approach to re-factoring:

a. analyze the cases where analysis can be skipped:

if (length < 24) return;
if (Acct != strAcct) return;
if (! Box.HasValues) return;

b. Combine them into a "short-circuiting" OR:
if(length < 24 || (Acct != strAcct) || (! Box.HasValues)
{
     // throw an error ?
     // log a call that wasn't evaluated ?

     // do nothing ? 
     return;
}

其中哪一项(没有,很多,或者,你实现的所有这些都可以通过你对该方法最频繁调用中最常见参数值的启发式知识来指导。

Which of these (none, many, or, all of them) that you implement can be guided by your heuristic knowledge of what the most common parameter-values are in the most frequent calls to the method.

if (code == strCode2)
{
    Method3();
}
else if (alk.Count > 1)
{
    if (Effect != strReceive && strVal == "A")
    {
        Method1();
    }
    else
    {
        Method2();
    }
}
else if // alk.Count <= 1
{
     // throw an error ?
     // log a call that wasn't evaluated ?
     // do nothing ?
}

注意:我喜欢在更复杂的评估之前梳理禁止因素的方法,因为,imho,它可以很容易地插入日志记录,或错误处理(或单元测试?),而不触及其余的代码。



imho,重新分解是技能,工艺,科学和艺术,当它考虑到你以前的经验和智慧,以及执行代码的独特应用程序环境。



然而,在现实世界中, WH如果你工作,和你一起工作,可能会限制你重新考虑的方式和时间。我已经看到一个场景,一个非常复杂的应用程序团队中的新程序员因为担心学习应用程序的结构和动态所需的非常艰苦的工作而被重新分解。不幸的是,重新分解它们确实引入了一些错误,并且需要昂贵的测试周期,并且必须丢弃它们的代码。是的,那里的管理层失败了,让新人有点自行离开。

Note: I like the approach of "teasing out" the "no go" factors before more complex evaluation, because, imho, it makes it easy to insert logging, or error handling (or, unit tests?), without touching the rest of the code.

imho, re-factoring is both a skill, craft, science, and art, when it takes into account your prior experience and wisdom, and the unique application context in which code is executed.

In the "real-world," however, where you work, and who you work with, may constrain how, and when, you re-factor. I have seen a scenario where a new programmer on the team of a very complex application got carried away with re-factoring in part due to being in fear of the very hard work required to learn the structure and dynamics of the application. Unfortunately, the re-factoring they did introduced some bugs, as well as requiring an expensive test cycle, and their code had to be discarded. Yes, there was a failure of management there in letting the newcomer kind of "go off on their own."


这篇关于我可以避免使用太多“if - else if”在下面的示例中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆