解决周期性和感知复杂性

时间:2015-10-03 13:10:21

标签: ruby cyclomatic-complexity rubocop

我的测试应用中有以下方法:

def on(definition, visit = false, &block)
  if @page.is_a?(definition)
    block.call @page if block
    return @page
  end

  if @context.is_a?(definition)
    block.call @context if block
    @page = @context unless @page.is_a?(definition)
    return @context
  end

  @page = definition.new(@browser)
  @page.view if visit

  @page.correct_url? if @page.respond_to?(:url_matches)
  @page.correct_title? if @page.respond_to?(:title_is)

  @model = @page

  block.call @page if block

  @page
end

当我对包含此方法的文件运行rubocop工具时,我得到以下响应:

C: Cyclomatic complexity for on is too high. [10/6]
C: Perceived complexity for on is too high. [10/7]

我不知道的是它的想法是什么"太复杂了#34;因此,我无法弄清楚如何解决问题。理想情况下,我不仅要告诉rubocop避免警告,因为它毫无疑问地告诉我某些有用。

对于复杂的方法,正如您所看到的,我有几个if调用,然后我必须使用@page对象以确保它已设置正确。 (此示例在上下文中是Watir-WebDriver对象。)

我同意这个方法很复杂,因为它需要检查@page是否已经存在并设置为某个内容以及检查@page是否应该与{{1}相同}。但是 - 再次,我不知道该怎么做。

此方法所在模块的完整代码如下:

https://github.com/jnyman/symbiont/blob/master/lib/symbiont/factory.rb

我最初认为我可以将其分解为不同的方法调用,这可能会降低每种方法的复杂性。但那意味着有人阅读我的代码必须跳到一系列不同的方法来理解@context正在做什么。对我来说,仅仅移动东西对于消除整体的复杂性似乎不大;相反,它只会在它周围徘徊。或者我错了吗?

此处的任何建议都表示赞赏。

更新代码

我已经有所减少了。这就是我现在所拥有的:

on

根据反馈,我删除了一个似乎没用的def on(definition, visit = false, &block) if @page.is_a?(definition) block.call @page if block return @page end if @context.is_a?(definition) block.call @context if block @page = @context return @context end @page = definition.new(@browser) @page.view if visit @model = @page block.call @page if block @page end 限定词。我还删除了两行我发现可以更好地使用其他地方(检查标题和网址)。

这已经消除了感知的复杂性"完全让我留下了这个:

unless

我似乎是"一点" (或任何术语)太复杂了。

1 个答案:

答案 0 :(得分:1)

有些地方您的代码是多余的。例如,你有这个:

if @page.is_a?(definition)
  ...
  return ...
end

这意味着,在任何要遵循此部分的部分中,您可以假设@page.is_a?(definition)不是true,除非您在此部分之后修改@page。不过,你有:

if @context.is_a?(definition)
  ... unless @page.is_a?(definition)
end