如何在Rails / Ruby中处理琐碎的“重复代码”气味

时间:2010-02-20 11:08:59

标签: ruby-on-rails ruby design-patterns

因此,我们都努力减少重复(DRY)和其他气味,并尽可能保持我们的代码良好和干净。对于Ruby代码,有很多工具可以检测气味,例如非常好的Caliber服务。

但是,似乎我对代码重复的定义与工具不同。我认为这可能与Ruby的做事方式有关,你几乎从不直接访问变量,而是通过方法调用。考虑一下Rails控制器的这个片段:

def update_site_settings
  SiteSettings.site_name = params[:site_name]
  SiteSettings.site_theme = params[:site_theme]
  expire_fragment('layout_header')
  flash[:notice] = t(:Site_settings_updated)
  redirect_to :controller => 'application', :action => 'edit_site_settings'
end

由于对“params”方法的两次调用,因此标记了代码重复警告。所以我的问题是,将params分配给局部变量真的会有所改进吗?我认为编写它的方式是最清晰简洁的方法,而params是一个方法而不是一个变量的事实很简单,就是Ruby中的“做生意的成本”。

我看错了吗?

编辑:在这种情况下,更漂亮的方式可能是进行SiteSettings.update_attributes(params)样式更新。如果您愿意,请考虑另一个代码段中的相同问题:

def update
  @mailing_list = MailingList.find(params[:id])

  if @mailing_list.update_attributes(params[:mailing_list])
    flash[:notice] = t:Mailing_list_updated
    redirect_to(mailing_lists_path)
    ...

2 个答案:

答案 0 :(得分:3)

有关DRY和代码味道概念的一件事要记住,它们是指南。它们可以帮助您思考如何组织和简化您的代码,更多的是森林树木的意义。虽然始终牢记这些概念是件好事,但在这么小的级别上挑错代码重复通常会最终在代码中引入不必要的复杂性或模糊性。代码的可理解性也应该是重要的,就像你说的那样,有时候最清晰简洁的代码与删除每一个重复痕迹的代码都不一样。

答案 1 :(得分:1)

我想你也可以声明一个Feature Envy代码气味的次要实例,虽然它确实有些微不足道。

也许可以引入MailingList上的类方法,因此控制器方法就像

def update
  if @mailing_list = MailingList.update_attributes_by_id(params)
    ...

class MailingList
  def self.update_attributes_by_id(params)
     id = params.delete(:id)
     find(id).update_attributes(params)
     ...

(未经测试,因此小心处理)

我会在现实生活中烦恼吗?可能不是,一方面,两部分的查找/更新事情是如此常见以至于人们立即理解它 - 有人像上面那样进入代码将不得不停下来思考一下,即使你有一个非常富有表现力的名字。

这些分析器(我在我自己的代码上运行Kevin Rutherford的reek)很棒,但是他们不了解上下文所以他们很少提供完美的信息。它们对于识别可能受益于注意力的区域很有用,但会有大量的误报,并且它们也会错过任何东西,所以它们需要在意识中使用。