Метод извлечения с продолжается

Если Вы собираетесь использовать несколько буферов, я думаю, что самая важная вещь состоит в том, чтобы установить скрытый так, чтобы она позволила Вам буферы коммутатора, даже если Вы не сохранили изменения в том, которое Вы оставляете.

5
задан Carl Manaster 20 July 2009 в 21:30
поделиться

4 ответа

Это один из тех забавных примеров, когда ни один шаблон не приведет вас туда.

Я бы работал над этим итеративно.

Сначала я попытался бы проверить, не смогу ли я » Не используйте раннее продолжение, чтобы удалить один из этих уровней «если». Это гораздо более четкий код для проверки наличия условия и возврата на раннем этапе (или, в вашем случае, для продолжения), чем для глубоко вложенных if.

Затем, я думаю, я бы взял некоторые из внутренних фрагментов и посмотрел, нельзя ли их извлечь в отдельный метод. Похоже, что первые два больших блока (внутри "if (test2 (a, c)) {" и его оператора else) очень похожи. Логика вырезания и вставки должна быть такой же.

Наконец, после того, как все прояснилось, вы можете приступить к рассмотрению вашей реальной проблемы - вам нужно больше классов. Весь этот оператор, вероятно, представляет собой трехстрочный полиморфный метод в 3-5 родственных классах.

Это очень близко к выбрасыванию и перезаписи кода, как только вы определите свои фактические классы, весь этот метод исчезнет и будет заменен чем-то настолько простым это больно. Тот факт, что это статический служебный метод, должен вам кое-что сказать - вы не хотите, чтобы один из них был в этом типе кода.

Редактировать (посмотрев еще немного): Здесь так много всего, что было бы весело пройти через это. Помните, что когда вы закончите, вам не нужно дублировать код - и я почти уверен, что все это можно было бы написать без единственного if - я думаю, что все ваши if - это случаи, которые можно / нужно легко обработать с помощью полиморфизма.

О, и в качестве ответа на ваш вопрос о том, что eclipse не хочет этого делать - даже не ПЫТАЙТЕСЬ с автоматическим рефакторингом с этим, просто сделайте это вручную. Материал внутри этого первого if () нужно вытащить в метод, потому что он практически идентичен предложению в его else ()!

Когда я делаю что-то подобное, я обычно создаю новый метод, перемещаю код из if в новый метод (оставив только вызов нового метода внутри if), затем запустите тест и убедитесь, что вы ничего не сломали.

затем переходите строка за строкой и проверяйте, нет ли разницы между if и его кодом else. Если есть, компенсируйте это, передав разницу в метод в качестве новой переменной. Убедившись, что все идентично, замените предложение else на вызов. Еще раз попробуй. Скорее всего, на этом этапе станет очевидным несколько дополнительных оптимизаций, вы, скорее всего, потеряете все, если объедините его логику с переменной, которую вы передали для различения двух вызовов.

Просто продолжайте делать такие вещи и повторять. Уловка с рефакторингом состоит в том, чтобы использовать очень маленькие шаги и тестировать между каждым шагом, чтобы убедиться, что ничего не изменилось.

замените предложение else на вызов. Еще раз попробуй. Скорее всего, на этом этапе станет очевидным несколько дополнительных оптимизаций, вы, скорее всего, потеряете все, если объедините его логику с переменной, которую вы передали для различения двух вызовов.

Просто продолжайте делать такие вещи и повторять. Уловка с рефакторингом состоит в том, чтобы использовать очень маленькие шаги и тестировать между каждым шагом, чтобы убедиться, что ничего не изменилось.

замените предложение else на вызов. Еще раз попробуй. Скорее всего, на этом этапе станет очевидным несколько дополнительных оптимизаций, вы, скорее всего, потеряете все, если объедините его логику с переменной, которую вы передали для различения двух вызовов.

Просто продолжайте делать такие вещи и повторять. Уловка с рефакторингом состоит в том, чтобы использовать очень маленькие шаги и тестировать между каждым шагом, чтобы убедиться, что ничего не изменилось.

8
ответ дан 18 December 2019 в 13:17
поделиться

continue в основном аналог раннего возврата, верно?

for (...) {
    doSomething(...);
}

private void doSomething(...) {
    ...
    if (...)
        return; // was "continue;"
    ...
    if (!doSomethingElse(...))
        return;
    ...
}

private boolean doSomethingElse(...) {
    ...
    if (...)
        return false; // was a continue from a nested operation
    ...
    return true;
}

Теперь я должен признаю, что я не совсем следовал вашей нынешней стратегии, поэтому я мог просто повторить то, что вы сказали. Если да, то я отвечу, что лучшего способа придумать не могу.

4
ответ дан 18 December 2019 в 13:17
поделиться

Если бы я столкнулся с вашей ситуацией, я бы посмотрел на использование других методов рефакторинга, таких как «заменить условное выражение на полиморфизм». При этом вы всегда должны делать что-то одно за раз, поэтому, если вы сначала хотите извлечь метод, у вас есть два варианта:

  1. Добавить флаг keepGoing
  2. Вызвать исключение из метода

Из этих двух вариантов , Я думаю, что флаг keepGoing лучше. Я бы не прекратил рефакторинг после того, как вы извлечете метод. Я уверен, что как только у вас будет метод меньшего размера, вы найдете способ удалить этот флаг и получить более чистую логику.

2
ответ дан 18 December 2019 в 13:17
поделиться

Я собираюсь обобщить здесь ответы, принимая ответ Билла К. как наиболее полный. Но у каждого есть что предложить, и я могу использовать любой из этих подходов в следующий раз, когда столкнусь с подобной ситуацией.


mmyers : Вырежьте тело цикла, вставьте его в новый метод и замените все continue с return s. Это работало очень хорошо, хотя возникли бы проблемы, если бы внутри цикла были другие операторы потока управления, такие как break и return.


Bill K : Итеративно разобрать его; ищите дублирование и устраняйте его. Воспользуйтесь преимуществами полиморфных классов, чтобы заменить условное поведение. Используйте очень маленькие шаги. Да; Все это хороший совет, который может применяться не только в этом конкретном случае.


Аарон : Используйте флаг keepGoing , чтобы заменить continue , либо выбросите исключение. Я не пробовал это, но думаю, что опция Exception - очень хорошая альтернатива, которую я не рассматривал.

0
ответ дан 18 December 2019 в 13:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: