【问题标题】:How to write a complicated condition如何写一个复杂的条件
【发布时间】:2013-04-08 15:48:19
【问题描述】:

当你有一个简单的条件和一个可能很复杂的主体时,条件结构很容易编写:

if simple_condition_expressed_in_one_liner
  complicated_body_that_may_be_long
  complicated_body_that_may_be_long
  complicated_body_that_may_be_long
end

但有时,你有一个复杂的条件和一个简单的身体,像这样:

if condition1 and
condition2 and
condition3 and
some_more_complicated_condition_that_cannot_be_written_on_a_single_line and
still_some_more_complicated_condition_that_cannot_be_written_on_a_single_line
  simple_body
end

在这种情况下,有没有好的写法?

【问题讨论】:

  • 你能给我们看一些_more_complicated_condition_that_cannot_be_written_on_a_single_line例子吗?
  • 请看我回复this question的第一部分。
  • 为什么不把一次性的逻辑扔进 lambda?
  • 最好在codereview.stackexchange.com 上询问。
  • 我期待为条件使用块结构。

标签: ruby coding-style conditional-statements


【解决方案1】:

我总是尝试重构为更小的描述性方法。

使用您的示例,而不是:

until (print "Username : "; gets.chomp == "user") and
      (print "Password : "; gets.chomp == "pa$$word")
  puts "Error, incorrect details"
end

我会使用:

def correct_user
  print "Username : "
  gets.chomp == "user"
end

def correct_password
  print "Password : "
  gets.chomp == "pa$$word"
end

until correct_user and correct_password
  puts "Error, incorrect details"
end

【讨论】:

    【解决方案2】:

    我个人把整个条件语句放到一个单独的方法中。这可能听起来很像已经建议的内容,但我将整个事情放入一个方法中,而不是分解它。

    simple_body if complicated_condition
    
    def complicated_condition
      condition1 and
      condition2 and
      condition3 and
      some_more_complicated_condition_that_cannot_be_written_on_a_single_line and
      still_some_more_complicated_condition_that_cannot_be_written_on_a_single_line
    end
    

    我可能会也可能不会将条件分解为更多方法,具体取决于条件是什么以及我以后是否会最终使用这些方法(太多的方法只用于一个目的开始变成代码味道)。

    它使代码可读(我可以浏览代码并查看它在做什么)和可维护(如果需要我可以更改条件并且我确切地知道它在哪里)。

    如果我把它放到一个类中,我会将该方法放在private 下,因为“外部”没有理由需要使用它。

    编辑: 如果条件需要在条件中使用变量时的值,也许考虑将binding 传递到方法中。

    opt = :mysql
    simple_body if complicated_condition(binding)
    
    opt = :oracle
    simple_body if complicated_condition(binding)
    
    def complicated_condition(b)
      condition1 and
      condition2 and
      condition3 and
      some_more_complicated_condition_that_cannot_be_written_on_a_single_line and
      still_some_more_complicated_condition_that_cannot_be_written_on_a_single_line and
      eval('opt', b) == :mysql
    end
    

    【讨论】:

      【解决方案3】:

      您应该考虑将其拆分为单独的方法。 阅读代码时很难在脑海中映射条件:

      if(condition1 and condition2 and ...)
      

      对比:

      if(isValidCondition())..
      

      【讨论】:

      • 具有代表性名称的方法
      【解决方案4】:

      Early returns 可能是在将 complex_condition 进行方法调用时的候选对象。

      simple_body if complex_condition
      
      def complex_condition
        condition1 or return # or return unless condition1 
        condition2 or return
        condition3 or return
        condition4 or return
        condition5
      end
      
      def condition4
        some_more_complicated_condition_that_cannot_be_written_on_a_single_line
      end
      
      def condition5
        still_some_more_complicated_condition_that_cannot_be_written_on_a_single_line
      end
      

      非常感谢您的想法,请随时发表评论!

      【讨论】:

        猜你喜欢
        • 2021-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-10
        • 1970-01-01
        • 2014-02-20
        • 2013-01-31
        • 1970-01-01
        相关资源
        最近更新 更多