代码重新分解 - 我应该将代码移动到单独的方法吗?

时间:2017-06-19 20:20:07

标签: ruby-on-rails ruby refactoring

我有一个控制器将已解析的文档与关键词数据库进行比较。典型的片段是循环遍历解析文档的封装循环,关键字数据库将数字与计数匹配并构建匹配单词数组。这是一个例子:

@key_words = KeyWords.all
@count = 0
@array_of_matching_words = []
@parsed_document.each do |a|
@key_words.each do |word|
  if a =~ /#{key_word.word}/
    @count = @count+1
    @array_of_matching_words = @array_of_matching_words.push "#{key_word.word}"
  end
end

实例化变量@count和@array_of_matching_words都传递给视图。我已经为其他单词数据库积累了大量的片段,我试图通过将一些代码移动到单独的方法来重新分解代码。

我考虑的一个选项是将代码移动到控制器中的私有方法

def get_the_number_and_the_list_of_matching_words
  @key_words = KeyWords.all
  @count = 0
  @array_of_matching_words = []
  @parsed_document.each do |a|
  @key_words.each do |word|
    if a =~ /#{key_word.word}/
      @count = @count+1
      @array_of_matching_words = @array_of_matching_words.push "#{key_word.word}"
    end
  end
end

然后我离开

get_the_number_and_the_list_of_matching_words

在我的动作控制器中,视图将同时获得@count和@array_of_matching_words。

我发现这种编码“风格”很糟糕。方法“get_the_number_and_the_list_of_matching_words”显示为蓝色,它不实例化任何内容,没有传递参数,实例化变量(@count,@ array_of_matching_words)都不可见(它们被隐藏在我的.rb文件底部的私有中方法部分)。这真的是重新分解代码的好方法还是有其他选择?当方法既不是实例方法也不是需要传递参数并返回新变量的方法时,将代码移动到方法是否有意义?

2 个答案:

答案 0 :(得分:0)

这可能是个人偏好问题,但现在就是这样。

我建议将分割方法尽可能小。好处有两个:

  • 考虑一位阅读该方法的新人。如果它只有几行(不管其他几种方法),那么更容易理解
  • 如果将逻辑委托给其他方法,测试会变得容易多了。您现在只需要测试在方法中调用方法,而不是测试所有逻辑

我同意在方法中使用不同的方法是混淆事物,特别是在涉及实例变量时,但是只需要查看方法并跟随其他方法调用它以了解正在发生的事情。

答案 1 :(得分:0)

像[{1}}这样的方法名称是荒谬的,如果它需要很长时间来表达它所做的事情,那么你的方法在设计上过于雄心勃勃。把它分成更小的块。

你的示例方法设置了三个不同的实例变量,取决于一个不作为参数传入的实例变量,它只是被假定为神奇地存在,除了定义{{之外没有明确的目标1}}。

通常包括变量名中的某些类型的东西是无关的信息。 get_the_number_and_the_list_of_matching_words在这里非常受欢迎。

你应该做的是打破在@array_of_matching_words@matching_words之间进行比较的逻辑,其中两者都作为参数传入。 Rails鼓励将这些方法纳入"关注"或者,如果它们适用于某个特定型号,那么它就适用于那里。

无论@key_words是什么,都可以扩展以产生所需的输出,例如,使代码看起来更像这样:

@parsed_document

然后,您可以使用KeyWords而不是单独的def prepare_key_words_matching @key_words = KeyWords.all @matching_words = KeyWords.matching(@parsed_document) end 变量。