我的测试应用程序中有以下方法:
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]
我没有得到它认为“太复杂”的东西,因此我无法弄清楚如何解决这个问题。理想情况下,我宁愿不只是告诉 rubocop 避免警告,因为毫无疑问它告诉我一些有用的东西。
正如您所看到的,就复杂的方法而言,我有几个if
调用,然后我必须使用该@page
对象以确保它设置正确。(这个例子,在上下文中,是一个 Watir-WebDriver 对象。)
我确实同意该方法很复杂,因为它需要检查是否@page
已经存在并设置为某物,以及检查是否@page
应该与@context
. 但是——再说一次,我不知道该怎么办。
该方法所在模块的完整代码在这里:
https://github.com/jnyman/symbiont/blob/master/lib/symbiont/factory.rb
我最初认为我可以将其分解为不同的方法调用,这可能会降低每种方法的复杂性。但这意味着阅读我的代码的人必须跳到一系列不同的方法来理解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
似乎确实没用的限定符。我还删除了两行我发现可以在其他地方更好地使用的行(检查标题和网址)。
这完全消除了“感知的复杂性”,只剩下了这个:
C: Cyclomatic complexity for on is too high. [7/6]
我似乎“一点”(或任何术语)太复杂了。