代码之家  ›  专栏  ›  技术社区  ›  F.P

如何避免多个嵌套IFs

  •  19
  • F.P  · 技术社区  · 14 年前

    我目前正在尝试重组我的程序,使之更面向对象,更好地实现已知的模式等。

    我有很多嵌套的IF语句,我想去掉它们。我该怎么办?我的第一个方法是在有例外的情况下完成。

    public static Boolean MyMethod(String param) {
     if (param == null)
      throw new NullReferenceException("param may not be null");
    
     if (param.Equals("none") || param.Equals("0") || param.Equals("zero"))
      throw new ArgumentNullException("param may not be zero");
    
     // Do some stuff with param
     // This is not executed if param is null, as the program stops a soon
     // as one of the above exceptions is thrown
    }
    

    static void Main() {
     try {
      Boolean test = MyClass.MyMethod(null); // Will throw an exception
     } catch (Exception ex) {
      MessageBox.Show(ex.Message, "Error");
     }
    

    我认为这是非常好的,因为它防止了嵌套语句,并且几乎所有的方法操作都很好地安排在一个级别上。

    与IF语句一样,方法如下所示

    public Boolean MyMethod(String param) {
     if (param != null) {
      if (!param.Equals("none") && !param.Equals("0") && !param.Equals("zero")) {
       // Do some stuff with param
      } else {
       MessageBox.Show("param may not be zero", "Error");
     } else {
      MessageBox.Show("param may not be null", "Error");
     }
    }
    

    我觉得很难看很难维持。

    好的

    6 回复  |  直到 14 年前
        1
  •  18
  •   Fredrik Mörk    14 年前

    这取决于他们的目的。在第一个示例中,if语句用于强制执行契约,确保方法的输入满足某些要求。在这些情况下,我自己的代码看起来很像你的代码。

    private void SomeMethod()
    {
        if (someCondition == true)
        {
            DoSomething();
            if (somethingElse == true)
            {
               DoSomethingMore();
            }
        }
        else
        {
            DoSomethingElse();
        }
    }
    

    在本例中,该方法似乎有几个职责,因此在本例中,我可能会选择将其拆分为几个方法:

    private void SomeMethod()
    {
        if (someCondition == true)
        {
            DoItThisWay();
        }
        else
        {
            DoSomethingElse();
        }
    }
    
    private void DoItThisWay()
    {
        DoSomething();
        if (somethingElse == true)
        {
           DoSomethingMore();
        }
    }
    

        2
  •  24
  •   Bertvan    14 年前

    您的问题称为箭头反模式。

    有一些实用的方法,例如您在示例中展示的保护语句,用于整个设计模式,避免if(和else)一起使用。。。

    关于如何解决这些问题的大量资源:

    http://www.codinghorror.com/blog/2006/01/flattening-arrow-code.html

    http://www.lostechies.com/blogs/chrismissal/archive/2009/05/27/anti-patterns-and-worst-practices-the-arrowhead-anti-pattern.aspx

    http://elegantcode.com/2009/08/14/observations-on-the-if-statement/

        3
  •  4
  •   Matt    14 年前

    你想调查吗 C#4 code contracts .

    经常使用的模式是 DDD specification pattern 用于抽象出if语句,尽管在您的情况下它可能不适合。

        4
  •  1
  •   Sidharth Panwar    14 年前
        5
  •  1
  •   Larry    14 年前

    也许 吧 AspectF 在这种情况下可以帮助您:

    public Boolean MyMethod(String param) {
     try {
      AspectF.Define
       .ErrorMsgIfNull(param, "must be not null")
       .ErrorMsgIfEquals(new string[] {"None", "Zero", "0"}, "may not be zero")
       //...
       // use your own "AspectFlets" you wrote
       //...
       .Do(() =>
        {
         // Do some stuff with param
         // This is not executed if param is null, as the program stops a soon
         // as one of the above exceptions is thrown
        });
    }
    

    上面代码中的方法只是不存在的示例,但是可以很容易地实现。

        6
  •  0
  •   ChrisBD    14 年前

    当然,在可能的情况下,我尝试用一个开关替换嵌套的if语句,但这并不总是可能的。