代码气候 - 太复杂的错误

时间:2017-01-29 18:08:51

标签: ruby-on-rails ruby code-climate

我在我的某个项目中使用了代码氛围,并且因为“太复杂”而导致出现错误"代码我不确定如何使代码变得不那么复杂?这是:

方法:

 def apply_json
    {
      total_ticket_count: payment_details.tickets.count,
      subtotal: payment_details.subtotal.to_f,
      discount: payment_details.discount.to_f,
      fees: payment_details.fees_total.to_f,
      total: payment_details.total_in_dollars.to_f,
      coupon: {
        amount: payment_details.coupon.amount,
        type: payment_details.coupon.coupon_type,
        name: payment_details.coupon.name,
        valid: payment_details.coupon.valid_coupon?,
      }
    }
 end

我把JSON隐藏在一个模型中。我的分支上的所有东西都对此非常期待?我不知道该怎么办?关于我如何使这不那么复杂的任何想法?

4 个答案:

答案 0 :(得分:3)

如果Code Climate认为某些事情过于复杂,但实际上很容易理解,我会不会太在意。 Code Climate应该可以帮助您编写更好,易读的代码。但它没有提供硬性规则。

如果您确实想要更改某些内容,可能需要将coupon子哈希的生成移至Coupon模型,因为它仅取决于coupon提供的值关联:

def apply_json
  {
    total_ticket_count: payment_details.tickets.count,
    subtotal:           payment_details.subtotal.to_f,
    discount:           payment_details.discount.to_f,
    fees:               payment_details.fees_total.to_f,
    total:              payment_details.total_in_dollars.to_f,
    coupon:             payment_details.coupon.as_json
  }
end

# in coupon.rb
def as_json
  {
    amount: amount,
    type:   coupon_type,
    name:   name,
    valid:  valid_coupon?
  }
end

可以使用payment_details进行类似的重构,但不确定此属性来自何处以及是否为关联模型。

答案 1 :(得分:3)

请忽略复杂性警告。

他们被误导了。

这些警告是基于假科学。

1976年在学术期刊中提出了循环复杂性,并且工具制造商已经采用了循环复杂性,因为它易于实施。

但原始研究存在缺陷。

原始论文提出了一种计算Fortran代码复杂度的简单算法,但没有给出任何证据证明计算出的数字实际上与代码的可读性和可理解性相关。 Nada,niente,零,zilch。

这是他们的摘要

  

本文描述了图论的复杂性度量和   说明了如何使用它来管理和控制程序   复杂。本文首先解释了图论的概念   应用并给出图形概念的直观解释   编程术语。几个实际Fortran的控制图   然后呈现程序以说明之间的相关性   直观的复杂性和图论的复杂性。一些   然后证明了图论的复杂性   例如,表明复杂性与物理尺寸无关   (添加或减去函数语句会留下复杂性   不变)和复杂性仅取决于a的决策结构   程序。

     

使用非结构化控制流程的问题也是如此   讨论。给出了非结构化控制图的表征   以及测量结构性的方法"一个程序是   发达。结构与还原性之间的关系是   用几个例子说明。

     

本文的最后一部分   处理与测试方法结合使用的测试方法   复杂性度量;确定了一种测试策略,规定了a   程序可以承认某个最低测试级别或者   程序可以在结构上减少

来源http://www.literateprogramming.com/mccabe.pdf

正如你所看到的那样,只有轶事证据才能说明直觉复杂性与图论理论复杂性之间的相关性。并且唯一的证据是代码可以被重写以具有由该度量定义的较低复杂度数。对于复杂性度量而言,这是非常不合理的证据,并且从那时起对于研究质量非常普遍。根据今天的标准,本文不会发表。

该论文的作者尚未进行过用户研究,他们的算法没有任何实际证据。从那时起,没有任何研究能够证明圈复杂度和代码理解之间的联系。更不用说这个复杂度指标是为Fortran而不是现代高级语言提出的。

确保代码理解的最佳方法是代码审查。只需简单地让其他人阅读您的代码并修复他们不理解的内容。

所以只需关闭这些警告即可。

答案 2 :(得分:1)

您正在尝试使用代码描述从一个复杂结构到另一个复杂结构的数据转换,这会产生很多复杂性"在代码气候等评论工具的眼中。

可能有用的一件事是用数据来描述转换:

PAYMENT_DETAILS_PLAN = {
  total_ticket_count: [ :tickets, :count ],
  subtotal: [ :subtotal, :to_f ],
  discount: [ :discount, :to_f ],
  fees: [ :fees_total, :to_f ],
  total: [ :total_in_dollars, :to_f ],
  coupon: {
    amount: [ :coupon, :amount ],
    type: [ :coupon, :coupon_type ],
    name: [ :coupon, :name ],
    valid: [ :coupon, :valid_coupon? ]
  }
}

这似乎不是一个巨大的变化,实际上它不是,但它提供了一些可衡量的好处。首先,您可以反映,您可以使用代码检查配置。另一种是,一旦你制定了这种格式,你就可以编写一个DSL来操纵它,过滤或扩充它等等。换句话说:它很灵活。

解释"计划"并不难:

def distill(obj, plan)
  plan.map do |name, call|
    case (call)
    when Array
      [ name, call.reduce(obj) { |o, m| o.send(m) } ]
    when Hash
      [ name, distill(obj, plan) ]
    end
  end.to_h
end

当你付诸行动时,这就是你得到的:

def apply_json
  distill(payment_details, PAYMENT_DETAILS_PLAN)
 end

也许这种方法可以帮助您在其他情况下做同样的事情。

答案 3 :(得分:0)

您可以提取优惠券subhash作为返回该subhash的方法。它会降低代码复杂性(对于codeclimate),但它并不是必需的。但是有些人认为该方法必须有5个或更少的字符串。他们在大多数用例中都是正确的。但这完全由你决定。

def apply_json
  {
    total_ticket_count: payment_details.tickets.count,
    subtotal: payment_details.subtotal.to_f,
    discount: payment_details.discount.to_f,
    fees: payment_details.fees_total.to_f,
    total: payment_details.total_in_dollars.to_f,
    coupon: subhash
  }
 end

def subhash
  {
    amount: payment_details.coupon.amount,
    type: payment_details.coupon.coupon_type,
    name: payment_details.coupon.name,
    valid: payment_details.coupon.valid_coupon?,
  }
end