ruby - 重构圈复杂度

标签 ruby refactoring

我有一段圈复杂度很高的代码:

def status_icon_name
  return 'icons/new.png' if mailgun_id.blank?
  return 'icons/hourglass.png' if mailgun_id.present? && log.blank?

  return 'icons/accept.png' if log['event'] == 'delivered'
  return 'icons/exclamation.png' if log['severity'].present? && log['severity'] == 'permanent'
  return 'icons/time.png' if log['event'] == 'accepted'
  return 'icons/error.png' if log['severity'] == 'temporary' 
  return 'icons/question.gif'
end

我如何重构它以消除圈复杂度?

我已阅读这篇博文 Cyclomatic complexity refactoring tips for javascript developers想出了这样的东西,但我觉得不对:

def status_icon_name
  lookup = [
    {
      condition: mailgun_id.blank?,
      icon_name: 'icons/new.png'
    },
    {
      condition: mailgun_id.present? && log.blank?,
      icon_name: 'icons/hourglass.png'
    },
    {
      condition: log.present? && log['event'] == 'delivered',
      icon_name: 'icons/accept.png'
    },
    {
      condition: log.present? && log['severity'].present? && log['severity'] == 'permanent',
      icon_name: 'icons/exclamation.png'
    },
    {
      condition: log.present? && log['event'] == 'accepted',
      icon_name: 'icons/time.png'
    },
    {
      condition: log.present? && log['severity'] == 'temporary',
      icon_name: 'icons/error.png'
    },
    {
      condition: true,
      icon_name: 'icons/question.gif'
    }
  ]

  lookup.find { |x| x[:condition] }[:icon_name]
end

最佳答案

在运行时构建这样的查找表会适得其反,您正在生成这个巨大的结构并评估所有这些条件,而不管它们的有效性。

也就是说,当你写:

lookup = [
  {
    condition: mailgun_id.blank?,
    icon_name: 'icons/new.png'
  }
]

这会立即得到评估并简化为:

lookup = [
  {
    condition: true,
    icon_name: 'icons/new.png'
  }
]

如果你想要延迟执行,你需要使用一个Proc:

LOOKUP = [
  {
    condition: Proc.new { mailgun_id.blank? },
    icon_name: 'icons/new.png'
  }
]

然后你会像这样执行:

LOOKUP.find { |x| instance_eval(&x[:condition]) }[:icon_name]

这样您就可以将查找表作为常量存储在类的顶部,并且只需定义一次,而不是每次方法调用一次。

关于ruby - 重构圈复杂度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45290202/

相关文章:

c# - 如何重用重新打开连接的代码?

refactoring - 限制 Webstorm 中的重构范围

java - 使用嵌套枚举重构方法

python - 用于 Web 开发的 GWT 或 Python 或 Ruby

arrays - 给定一个大小为 y 的数组,其中包含大小为 n 的数组,我如何使用 Ruby 返回所有逻辑组合?

ruby - 安装 ImageMagick 并在应用图标覆盖时再次启动你的车道错误

ruby-on-rails - 在 Ruby On Rails Controller 方法中使用事务

无需重构的 Android Studio 重命名

sql - 重构SQL

ruby - 如何使用可枚举函数在二维数组中添加每组总和?