我的测试应用中有以下方法:
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
我似乎是"一点" (或任何术语)太复杂了。
答案 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