如何重构以摆脱实例变量?

时间:2011-04-12 21:39:21

标签: ruby refactoring

我有很多像这样的方法:

def lab1
  setup
  business_processing
rescue Exception => e
  handle_error('custom error message for lab1', e)
end

def lab2
  setup
  business_processing
rescue Exception => e
  handle_error('custom errror message for lab2', e)
end

我将上面的代码重构为以下内容:

def lab1
  with_setup_and_error_handling do
    @error_message = 'error in lab1'
    business_processing
  end
end

def with_setup_and_error_handling(&block)
  setup
  block.call
rescue Exception => e
  handle_error(@error_message, e)
end

新代码有效但会导致error_message成为实例变量。有没有更好的方法来重构它?

当有人查看重构的代码时,他们会看到实例变量,但不清楚它在哪里被使用,所以我对它不满意。

4 个答案:

答案 0 :(得分:4)

将错误消息作为de setup方法的参数:

def lab1
  with_setup_and_error_handling('error in lab1') do
    business_processing
  end
end

def with_setup_and_error_handling(error_message, &block)
  setup
  block.call
rescue Exception => e
  handle_error(error_message, e)
end

答案 1 :(得分:1)

为什么不将错误消息作为参数传递给with_setup_and_error_handling?对我来说似乎是一个明显的解决方案。

答案 2 :(得分:1)

这是一个XY问题*。

您认为需要“摆脱”实例变量的事实是一种表明设计不佳的气味。在这种情况下,糟糕的设计是由于不正确使用/理解范围(实例变量)而导致的状态泄漏。 “它无法正常工作”并不足以使某些实例成为变量。

* http://www.perlmonks.org/index.pl?node_id=542341

答案 3 :(得分:1)

如果您要更改的是每个进程的错误消息,那么为什么不通过以下方式重构代码:

def lab(version)
  begin
    setup
    business_processing
  rescue Exception => e
    handle_error("error in lab#{version}", e)
  end
end

如果有必要保留各个labN方法,请执行以下操作:

def lab1
  self.lab 1
end

def lab2
  self.lab 2
end