如何重构下面的ruby代码?

时间:2015-08-11 16:02:49

标签: ruby oop

此代码由if / else阶梯组成。它检查@tokens[0]值并根据其内容调用该函数:

if @tokens[0] == "add"
  @calculator.add(@tokens[1].to_f)
elsif @tokens[0] == "subtract"
  @calculator.subtract(@tokens[1].to_f)
elsif @tokens[0] == "multiply"
  @calculator.multiply(@tokens[1].to_f)
elsif @tokens[0] == "divide"
  @calculator.divide(@tokens[1].to_f)
elsif @tokens[0] == "sqr"
  @calculator.sqr
elsif @tokens[0] == "sqrt"
  @calculator.sqrt
elsif @tokens[0] == "cube"
  @calculator.cube
elsif @tokens[0] == "cubert"
  @calculator.cubert
end

我使用hashmap来重构代码。除了hashmap之外,还有其他方法可以重构它吗?

5 个答案:

答案 0 :(得分:2)

我试图阅读想法:

@calculator.public_send \
  case @tokens[0]
  when 'add', 'subtract', 'multiply', 'divide'
    @tokens[0], @tokens[1].to_f
  when 'sqr', 'sqrt', 'cube', 'cubert'
    @tokens[0]
  else fail 'Unsupported operation'
  end

答案 1 :(得分:2)

像这个未经测试的代码?

action = @tokens[0].to_sym
case action
when :add, :subtract, :multiply, :divide
  @calculator.send(action, @tokens[1].to_f)
else
  @calculator.send(action)
end

答案 2 :(得分:1)

你可以使用这样的东西

have_param = ["add", "subtract", "multiply", "divide"]

known_tokens = ["add", "subtract", "multiply", "divide", "sqr", "sqrt", "cube", "cubert"]

t_0_value = @tokens[0]
if known_tokens.include?(t_0_value)
  ( have_param.include?(t_0_value) ? @calculator.send(t_0_value, @tokens[1].to_f) : @calculator.send(t_0_value) )
end

答案 3 :(得分:1)

@calculator.send(@tokens[0],
  *case @tokens[0]
  when "add".freeze, "subtract".freeze, "multiply".freeze, "divide".freeze
    @tokens[1].to_f
  when "sqr".freeze, "sqrt".freeze, "cube".freeze, "cubert".freeze
    nil
  end
)

答案 4 :(得分:0)

有很多方法可以重构这个,这里很容易:

你可以使用看起来更干净的case语句,如下所示:

case @tokens[0]
when "add" 
  @calculator.add(@tokens[1].to_f)
when "subtract"
  @calculator.subtract(@tokens[1].to_f)
when "multiply"
  @calculator.multiply(@tokens[1].to_f)
when "divide"
  @calculator.divide(@tokens[1].to_f)
when "sqr"
  @calculator.sqr
when "sqrt"
  @calculator.sqrt
when "cube"
  @calculator.cube
when "cubert"
  @calculator.cubert
end

您可以将条件放在自己的哈希中:

cases = { "add" => @calculator.add(@tokens[1].to_f),
"subtract" => @calculator.subtract(@tokens[1].to_f),
"multiply" => @calculator.multiply(@tokens[1].to_f),
"divide" => @calculator.divide(@tokens[1].to_f),
"sqr" => @calculator.sqr,
"sqrt" => @calculator.sqrt,
"cube" => @calculator.cube,
"cubert" => @calculator.cubert }

cases[@tokens[0]]

您可以使用eval来调用该函数,并且您不需要为每个操作创建一个案例:

case @tokens[0]
when 'add', 'subtract', 'multiply', 'divide'
  eval("@calculator.#{@tokens[0]}(#{@tokens[1].to_f})")
when 'sqr', 'sqrt', 'cube', 'cubert'
  eval("@calculator.#{@tokens[0]}")
end

这将调用该函数并在令牌[0]上使用.to_f,如果它在数组中

@calculator.send(tokens[0], ['add', 'subtract', 'multiply', 'divide'].include? tokens[0] ? tokens[1].to_f : tokens[1])

你可以把它放在@calculator类中,并且总是调用@ calculator.calculate(tokens)

def calculate(tokens)
    send(tokens[0], ['add', 'subtract', 'multiply', 'divide'].include? tokens[0] ? tokens[1].to_f : tokens[1])
end