2015-10-03 3 views
1

У меня есть следующий метод в моем тестовом приложении:Разрешающих цикломатические и воспринимаемая Сложность

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] 

Я, кажется, «одна точка» (или любой другой терминологии) слишком сложна.

+0

Ваш код кричит, что он не может вывести идентификатор объекта/тип класса на нем. Вы постоянно спрашиваете: «Эй, это вы, знаете ли вы, как это сделать?». Это нормально для безопасности, но, скорее всего, вы должны подтвердить свой вход где-то еще, прежде чем этот метод можно будет вызвать. – Anthony

+0

Хм. Я не понимаю, как я мог. (Это не то, что я говорю, что это невозможно!) Проблема в том, что метод фабрики 'on' в контексте называется так:' on (SomePage) '. Это может произойти в любом месте тестового скрипта. Кроме того, вы можете иметь 'on (SomePage)', а затем 'on (SomeOtherPage)'. Для логики важно знать, что SomeOtherPage не является SomePage. Но вы также можете сделать 'on_new (SomePage)', что означает, что SomePage - это SomePage, но его новый - другой экземпляр. Поэтому проблема заключается в том, что я не знаю, что будет делать сценарий. Тем не менее, принимая ваши слова близко к сердцу, я посмотрю, смогу ли я его очистить. –

ответ

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 
+0

Ах! Хорошая точка зрения. Да, если спецификатор, похоже, не нужен. Если я возьму это, я удалю одну «точку» из моей сложности в соответствии с rubocop. Это ставит меня в зависимость от Cyclomatic, потому что она слишком высока. [9/6] 'и' Описанная сложность для слишком велика. [9/7] '. Интересно. Таким образом, кажется, что сложность основана на моих условностях, по крайней мере в некоторой степени. –

+0

Прошло некоторое время, и я понимаю, что я ничего не принимал к этому. Этот ответ, безусловно, поставил меня на путь понимания того, где мне нужно было сделать свой акцент; следовательно, принимать (сразу же просроченные). –

Смежные вопросы