У меня есть следующий метод в моем тестовом приложении:Разрешающих цикломатические и воспринимаемая Сложность
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
классификатор, который, казалось бесполезным. Я также удалил две строки, которые я нашел, чтобы лучше использовать где-то в другом месте (проверяя заголовок и URL-адрес).
Это устранило «ощущаемой сложность» целиком и оставил меня только это:
C: Cyclomatic complexity for on is too high. [7/6]
Я, кажется, «одна точка» (или любой другой терминологии) слишком сложна.
Ваш код кричит, что он не может вывести идентификатор объекта/тип класса на нем. Вы постоянно спрашиваете: «Эй, это вы, знаете ли вы, как это сделать?». Это нормально для безопасности, но, скорее всего, вы должны подтвердить свой вход где-то еще, прежде чем этот метод можно будет вызвать. – Anthony
Хм. Я не понимаю, как я мог. (Это не то, что я говорю, что это невозможно!) Проблема в том, что метод фабрики 'on' в контексте называется так:' on (SomePage) '. Это может произойти в любом месте тестового скрипта. Кроме того, вы можете иметь 'on (SomePage)', а затем 'on (SomeOtherPage)'. Для логики важно знать, что SomeOtherPage не является SomePage. Но вы также можете сделать 'on_new (SomePage)', что означает, что SomePage - это SomePage, но его новый - другой экземпляр. Поэтому проблема заключается в том, что я не знаю, что будет делать сценарий. Тем не менее, принимая ваши слова близко к сердцу, я посмотрю, смогу ли я его очистить. –