Есть ли такая вещь, как слишком много встроенных операторов if? - PullRequest
6 голосов
/ 30 июня 2011

В настоящее время я работаю над небольшим количеством кода, который (я считаю) требует довольно много встроенных операторов if.Есть ли какой-то стандарт на то, сколько операторов if будет встраиваться?Большинство моих поисков в Google оказалось связано с Excel ... не знаю почему.

Если есть стандарт, почему?Это для удобства чтения или для того, чтобы код работал более плавно?На мой взгляд, имеет смысл, что это будет в основном для удобочитаемости.

Пример моей структуры if:

if (!all_fields_are_empty):
    if (id_search() && validId()):
        // do stuff
    else if (name_search):
        if (name_exists):
            if (match < 1):
                // do stuff
        else:
            // do stuff
    else if (name_search_type_2):
        if (exists):
            if (match < 1):
                // do stuff
        else:
            // do stuff
else:
    // you're stupid

Я слышал, что есть ограничение на 2-3 вложенныхдля циклов for / while, но есть ли какой-то стандарт для операторов if?

Обновление: У меня есть несколько лет за плечами.Пожалуйста, не используйте это много if утверждений.Если вам нужно так много, ваш дизайн, вероятно, плохой.Сегодня я ЛЮБЛЮ, когда могу найти элегантный способ сделать это с минимальными if утверждениями или switch делами.Код становится чище, его легче тестировать и легче поддерживать.Обычно.

Ответы [ 6 ]

7 голосов
/ 30 июня 2011

Как упоминал Рэнди, причиной такого рода кода в большинстве случаев является плохой дизайн приложения. Обычно я пытаюсь использовать «процессорные» классы в вашем случае.

Например, если есть какой-то общий параметр с именем «операция» и 30 различных операций с разными параметрами, вы можете создать интерфейс:

interface OperationProcessor {
   boolean validate(Map<String, Object> parameters);
   boolean process(Map<String, Object> parameters);
}

Затем реализуйте множество процессоров для каждой необходимой операции, например:

class PrinterProcessor implements OperationProcessor {
    boolean validate(Map<String, Object> parameters) {
       return (parameters.get("outputString") != null);
    }
    boolean process(Map<String, Object> parameters) {
       System.out.println(parameters.get("outputString"));
    }
}

Следующий шаг - вы регистрируете все свои процессоры в некотором массиве при инициализации приложения:

public void init() {
    this.processors = new HashMap<String, OperationProcessor>();
    this.processors.put("print",new PrinterProcessor());
    this.processors.put("name_search", new NameSearchProcessor());
    ....
}

Итак, ваш основной метод становится примерно таким:

String operation = parameters.get("operation"); //For example it could be 'name_search'
OperationProcessor processor = this.processors.get(operation);
if (processor != null && processor.validate()) { //Such operation is registered, and it validated all parameters as appropriate
   processor.process();
} else {
   System.out.println("You are dumb");
}

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

5 голосов
/ 30 июня 2011

Я не думаю, что есть предел, но я бы не советовал встраивать их больше - их слишком сложно читать, сложно отлаживать и сложно тестировать. Попробуйте взглянуть на пару замечательных книг, таких как Рефакторинг , Шаблоны проектирования и, возможно, Чистый код

4 голосов
/ 30 июня 2011

Технически, я не знаю каких-либо ограничений для вложения.

Это может быть признаком плохого дизайна, если вы обнаружите, что углубляетесь.

Часть того, что вы опубликовали, выглядитэто может быть лучше использовать в качестве case заявления.

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

edit:

Вы также можете подумать о том, чтобы иметь класс, подобный SearchableObject().Вы можете создать базовый класс с общей функциональностью, а затем наследовать ID, Имя и т. Д., И этот блок управления верхнего уровня будет значительно упрощен.

1 голос
/ 30 июня 2011

Технически вы можете иметь столько, сколько захотите, но если у вас много, это может быстро сделать код нечитабельным.

То, что я обычно делаю, выглядит примерно так:

if(all_fields_are_empty) {
    abuseuser;
    return;
}

if(id_search() && validId()) {
  //do stuff
  return;
}

if(name_search)
{
  if(name_exists)
    //do stuff
    return
  else
    //do stuff
    return
}

Я уверен, что вы получите картину

0 голосов
/ 12 сентября 2017

Tl; Dr Вам не нужно больше 10-15 путей, хотя какой-либо один метод

То, на что вы здесь ссылаетесь, это Цикломатическая сложность .

Цикломатическая сложность - это программная метрика (измерение), используемая для обозначения сложности программы.Это количественная мера количества линейно независимых путей в исходном коде программы.Он был разработан Томасом Дж. МакКейбом-старшим в 1976 году.

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

Существует ли какой-либо стандарт для того, сколько операторов if будет встраиваться?

И да и нет.Обычно считается (и сам МакКейб утверждал), что цикломатическая сложность, превышающая 10 или 15, слишком высока и является признаком того, что код должен быть реорганизован.

Одним из оригинальных приложений McCabe было ограничение сложности процедур при разработке программ;он рекомендовал программистам учитывать сложность модулей, которые они разрабатывают, и разбивать их на более мелкие модули всякий раз, когда цикломатическая сложность модуля превышала 10. [2]Эта практика была принята методологией структурированного тестирования NIST с наблюдением, что со времени первоначальной публикации McCabe, цифра 10 получила существенные подтверждающие доказательства, но в некоторых случаях может быть целесообразно ослабить ограничение и разрешить модули со сложностью, какдо 15. Поскольку методология признала, что были случайные причины для выхода за пределы согласованного предела, она сформулировала свою рекомендацию следующим образом: «Для каждого модуля либо ограничьте цикломатическую сложность до [согласованного предела], либо предоставьте письменное объяснениео том, почему был превышен лимит. "[7]

Это на самом деле не жесткое правило и может быть проигнорировано в некоторых обстоятельствах.Смотрите этот вопрос Какова самая высокая цикломатическая сложность любой функции, которую вы поддерживаете?И как бы вы занялись рефакторингом? .

почему?Это для удобочитаемости или для того, чтобы код работал более плавно?

По существу это для удобочитаемости, которая должна обеспечить бесперебойную работу вашего кода.Цитировать Мартин Фаулер

Любой дурак может написать код, понятный компьютеру.Хорошие программисты пишут код, понятный людям.

0 голосов
/ 30 июня 2011

Единственным техническим ограничением на количество вложенных блоков if / else в Java, вероятно, будет размер вашего стека. Стиль - это другое дело.

Кстати: что с двоеточиями?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...