Считаете ли вы эту технику "ПЛОХОЙ"? - PullRequest
20 голосов
/ 28 октября 2008

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

Так что я делаю трюк так:

do
{
   bool isGood = true;

   .... some code

   if(!isGood)
       break;

   .... some more code

   if(!isGood)
       break;

   .... some more code

 } while(false);

 ..... some other code, which has to be executed.

Я использую «фальшивый» цикл, который запускается один раз, и я могу прервать его, набрав break или continue .

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

Ответы [ 28 ]

2 голосов
/ 28 октября 2008

У меня нет проблем с этим, пока код читается.

2 голосов
/ 28 октября 2008

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

1 голос
/ 28 октября 2008

А как насчет функционального подхода?


        void method1()
        {
            ... some code
            if( condition )
                method2();
        }

        void method2()
        {
            ... some more code
            if( condition )
                method3();
        }

        void method3()
        {
            ... yet more code
            if( condition )
                method4();
        }
1 голос
/ 28 октября 2008

Зависит от того, какие есть альтернативы. Вы должны признать, что код, который вы разместили, несколько уродлив. Я бы не сказал, что это понятно. Это своего рода хак. Так что, если использовать другое решение для кодирования, будет хуже, тогда хорошо. Но если у вас есть лучшая альтернатива, не позволяйте оправданию "это достаточно хорошо" успокоить вас.

1 голос
/ 28 октября 2008

Для меня то, что ты делаешь, плохо во многих отношениях. Цикл можно заменить, поместив этот код в метод.

Я лично считаю, что если вы должны положить! перед вашими условиями вы ищете не ту вещь. Для удобства чтения сделайте, чтобы ваш логический соответствовал тому, что вы проверяете. Вы действительно проверяете, есть ли ошибка или какое-то плохое состояние, поэтому я бы предпочел: If (isError) { //Do whatever you need to do for the error and return; } над If (!isGood) { //Do something }

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

Одной из первых вещей, над которыми я работал 28 лет назад, была программа на Фортране, которая всегда должна была проверять наличие графического устройства. Кто-то принял великое решение вызвать логическое значение для этого LNOGRAF, поэтому, если бы было доступно графическое устройство, это было бы ложным. Я полагаю, что это было установлено из-за ложной эффективности, проверка устройства вернула ноль, если было графическое устройство. Во всем коде все проверки должны были проверить, доступно ли графическое устройство. Это было полно:

If (.NOT. LNOGRAF)

Я не думаю, что был один:

If (LNOGRAF)

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

1 голос
/ 28 октября 2008

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

Нет ничего плохого в использовании исключений. Исключения являются частью логики приложения. Рекомендация об исключениях заключается в том, что они должны быть относительно редкими во время выполнения.

1 голос
/ 28 октября 2008

Во-первых, если вы просто хотите получить ответ на вопрос, является ли эта структура кода или идиома «плохой», я бы подумал, что это так. Тем не менее, я думаю, что это признак плохой декомпозиции, а не то, является ли ваш код «хорошим» или «плохим».

Я бы подумал, что потребуется гораздо более качественный анализ и рефакторинг, чтобы иметь возможность продолжить рассмотрение источника проблемы, а не просто смотреть на код. Если вы можете сделать что-то вроде:

if (condition1(...) && condition2(...) && condition3(...) && ... && conditionN(...)) {
    // code that ought to run after all conditions
};
// code that ought to run whether all conditions are met or not

Тогда я думаю, что это будет более "читабельным" и более идиоматическим. Таким образом, вы можете сделать такие функции, как:

bool conditionN(...) {
    if (!real_condition) return false;
    // code that ought to run
    return true;
};

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

1 голос
/ 28 октября 2008

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

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

Если случай, когда это не «хорошо», действительно исключительный, то выбрасывание исключений будет лучшим выбором.

1 голос
/ 28 октября 2008

Я бы посчитал это плохой практикой. Я думаю, что было бы более идиоматичным и в целом более понятным, если бы вы сделали это функцией и изменили разрывы на возвраты.

1 голос
/ 28 октября 2008

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

Как насчет использования более обычных языковых функций, таких как функции?

bool success = someSensibleFunctionName();

if(success)
{
   ...
}

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