帮助重构这个令人讨厌的Ruby if / else语句

所以我有这个大的,毛茸茸的if / else语句。 我将一个跟踪号码传递给它,然后确定它是什么类型的跟踪号码。

我怎样才能简化这件事? 特别希望减少代码行数。

if num_length < 8
  tracking_service = false
else
  if number[1, 1] == 'Z'
    tracking_service = 'ups'
  elsif number[0, 1] == 'Q'
    tracking_service = 'dhl'
  elsif number[0, 2] == '96' && num_length == 22
    tracking_service = 'fedex'
  elsif number[0, 1] == 'H' && num_length == 11
    tracking_service = 'ups'
  elsif number[0, 1] == 'K' && num_length == 11
    tracking_service = 'ups'
  elsif num_length == 18 || num_length == 20
    check_response(number)
  else
    case num_length
    when 17
      tracking_service = 'dhlgm'
    when 13,20,22,30
      tracking_service = 'usps'
    when 12,15,19
      tracking_service = 'fedex'
    when 10,11
      tracking_service = 'dhl'
    else
      tracking_service = false  
    end  
  end
end

是的我知道。 这很讨厌。


尝试这个。 我使用case和正则表达式重写了它。 我还使用:symbols而不是"strings"作为返回值,但您可以将其更改回去。

tracking_service = case number
  when /^.Z/ then :ups
  when /^Q/ then :dhl
  when /^96.{20}$/ then :fedex
  when /^[HK].{10}$/ then :ups
else
  check_response(number) if num_length == 18 || num_length == 20
  case num_length
    when 17 then :dhlgm
    when 13, 20, 22, 30 then :usps
    when 12, 15, 19 then :fedex
    when 10, 11 then :dhl
    else false
  end
end

根据跟踪代码是否为ruby对象,您还可以将帮助器放入其类定义中:

class TrackingCode < String 
  # not sure if this makes sense for your use case
  def ups?
    self[1,1] == 'Z'
  end
  def dhl?
    self[0,1] == 'Q'
  end
  def fedex?
    self.length == 22 && self[0, 2] == '96'
  end
  # etc...
end

然后你的条件变成:

if number.ups?
  # ...
elsif number.dhl?
  # ...
elseif number.fedex?
end

在您使用跟踪代码的隐含功能时使用的一个简化条件。 同样,如果你采取循环方法,你的循环也会更清晰:

%w(ups? dhl? fedex?).each do |is_code|
  return if number.send(is_code)
end

甚至:

%w(ups? dhl? fedex?).each do |is_code|
  yield if number.send(is_code)
end

这种方法看起来像是为了速度而写的。 您可以使用minhash作为替代品,但我认为代码相当干净并且不需要重构。 Rubyists倾向于被不必要的结构所厌恶,但往往需要模拟真实世界的情况和/或提供性能提升。 关键字应该是不必要的。

链接地址: http://www.djcxy.com/p/58479.html

上一篇: Help refactoring this nasty Ruby if/else statement

下一篇: login