Вопрос

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

Это было полезно?

Решение

Глубокое отступление есть обычно Не проблема, если каждая функция/метод в вашей программе выполняет одну вещь. Иногда это мощь Будьте необходимым для гнездящихся в глубине нескольких уровней, но я могу честно сказать, что я писал только глубоко отступив код несколько раз за 12+ лет кодирования.

Другие советы

Лучшее, что вы можете сделать, это извлечь методы:

int Step1(int state)
{
    if (state == 100)
    {
        return Step2(state);
    }
    else
    {
        return Step3(state);
    }
}

int Step2(int state)
{
    if (state != 100)
    {
        throw new InvalidStateException(2, state);
    }

    // ....
}

Может, вы могли бы рассмотреть охранники?

вместо

public void DoSomething(int value){
    if (someCondition){
           if(someOtherCondition){
                if(yetAnotherCondition){
                       //Finally execute some code
                }
           }
    }
} 

Делать

public void DoSomething(int value){
    if(!(someCondition && someOtherCondition && yetAnotherCondition)){
        return;
        //Maybe throw exception if all preconditions must be true
    }
    //All preconditions are safe execute code
}

Если у вас когда -нибудь появится шанс, что я рекомендую, что вы прочитали код, завершенным Стивом Макконнеллом. У него много отличных советов по этим темам.

http://www.amazon.com/code-complete-practical-handbook-construction/dp/0735619670/ref=pd_sim_b_6

Для получения дополнительной информации о «охранниках» см.: https://sourcemaking.com/refactoring/replace-nested-conditional-with-guard-clauses

Инвертировать ifс

Вместо:

if (foo != null)
{
    something;
    something;
    if (x)
    {        
       something;
    }
    something;
}
else
{
    boohoo;
}

Я бы напишет:

if (foo == null)
{
    boohoo;
    return;
}
something;
something;
if (x)
{        
   something;
}
something;

То же самое относится и к if-else блоки. Если else короче / менее вложен, а затем верните их.

Проверьте значения параметров в одном месте

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

Как правило, я видел, что глубоко отступаемый код обычно является проблематичным кодом. Если вы столкнетесь с этой проблемой, отступите и оцените, делает ли ваша функция слишком много вещей.

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

Разбейте вложенные компоненты (особенно повторяющиеся) на отдельные функции (это проще, если ваш язык поддерживает закрытие) или замените серию вложенных петель на рекурсию.

Кроме того, отступить два пространства вместо четырех.

Я не вижу глубоких вмешательств как категориальную проблему, которую нужно удалить (при этом я не вижу рефакторирования как истинный ответ для всего).

Обычно вместо вложенных IFS мне нравится писать логические утверждения:

if (foo && bar && baz) 

скорее, чем

if foo 
 if bar
   if baz

Я не верил в это сам, но, согласно коду, завершено, это подходящее место для использования break (Если ваша команда находится на борту). Я полагаю, что это более приемлемо для программистов C ++, где, где break используется в switch заявления, чем с программистами Delphi, где break используется только тогда, когда вам не хочется писать while петля.

Следление - это действительно мысль, чтобы сражаться, действительно. Что я научился делать, так это сначала разделить метод на кусочки, а затем использовать странный трюк, чтобы пропустить каждую следующую часть, если один кусок вышел из строя. Вот пример:

Вместо :

 {if (networkCardIsOn() == true)
     {if (PingToServer() == true)
        {if (AccesLogin(login,pass) == true)
             {if (nextCondition == true)
                ...
         }
     }
 }

Я сейчас пишу:

 {vbContinue = true;

 if (vbContinue) {
       vbContinue = networkCardIsOn();
       if (vbContinue == false) {
             code to Handle This Error();
       } 
 }

 if (vbContinue) {
       vbContinue = PingToServer();
       if (vbContinue == false) {
             code to HandleThisError2();
       } 
 }

 if (vbContinue) {
       vbContinue = AccesLogin(login,pass);
      if (vbContinue == false) {
             HandleThisErrorToo();
       } 
 }
 ...

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

Фактически, усиление, введенное этой «техникой», заключается в том, что сложность кода действительно разделена, потому что код менее плотный.

Читая код, вам не нужно ничего вспоминать о прошлых условиях: если вы находитесь в этой точке x в коде, предыдущие шаги выполняются и преуспели.

Другая выгода заключается в том, что «путь и условие побега» от всех этих вложенных «if-else» упрощается.

Лицензировано под: CC-BY-SA с атрибуция
scroll top