Стиль Вопрос: если блок в или вокруг функции? - PullRequest
3 голосов
/ 03 сентября 2010

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

Вариант 1: обернуть все вызовы функций в блок if:

if(defined('FOO_BAR_ENABLED')) {
   foobar();
}

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

Вариант 2: проверить константу в самой функции:

function foobar() {
  if(!defined('FOO_BAR_ENABLED')) {
    return;
  }
  //do stuff 
}

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

Ответы [ 6 ]

10 голосов
/ 03 сентября 2010

Могу ли я предложить переименовать функцию в FoobarIfEnabled (), а затем выполнить проверку в функции?

Свободно крадет у великого, независимого от языка ответ на один из моих собственных вопросов , при программировании у нас возникают следующие проблемы:

  1. Сделайте это правильно.
  2. Проясни.
  3. Сделайте это лаконичным.
  4. Сделай это быстро. ... в таком порядке.

Если вы выполните проверку вне функции, вы можете в конечном итоге пропустить ее в одном месте. И если вы хотите изменить поведение, вам нужно найти все места, которые он вызывает, и исправить это. Это кошмар обслуживания, который нарушает принцип 1. Добавив «IfEnabled» или что-то в этом роде, теперь это не только правильно, но и понятно. Как ты можешь победить это?

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

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

2 голосов
/ 03 сентября 2010

Вариант 3:

void maybe_foobar() {
   if(defined('FOO_BAR_ENABLED')) really_foobar();
}

void really_foobar() {
    // do stuff
}

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

Если нет обстоятельств, при которых кто-либо мог бы действительно «делать что-то», когда FOO_BAR_ENABLED не определен, то я бы выбрал ваш вариант 2 (и, возможно, вызову функцию do_stuff_if_possible вместо foobar, если имя foobar вызывало путаницу в том, влечет ли его вызов на самом деле что-либо). Если «делать что-то» всегда допустимо, но некоторые пользователи делают это условно, то я бы выбрал свой вариант 3.

Вариант 1 приведет к копированию и вставке кода, который почти всегда является плохим знаком.

[Редактировать: вот вариант 4, который, я подозреваю, слишком сложен, но вы никогда не знаете:

void if_enabled(string str, function f) {
    if (defined(str + '_ENABLED')) f();
}

Тогда вы называете это с:

if_enabled('FOO_BAR', foobar);

Очевидно, что есть некоторые проблемы, связанные с тем, как ваш язык обрабатывает функции, и есть ли способ передать произвольные параметры и возвращаемое значение через if_enabled.]

1 голос
/ 03 сентября 2010

В заголовочном файле, если foobar всегда принимает одинаковое количество аргументов,

#ifdef ENABLE_FOOBAR
#define maybe_foobar(x) foobar(x)
#else
#define maybe_foobar(x)
#endif

Не уверен, как это сделать на диалектах C ++ или более старых C, если foobar может принимать переменное число аргументов.

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

1 голос
/ 03 сентября 2010

Подпадает ли под условие if ответственность функции? Есть ли вариант использования для вызова функции без if?

Если условие всегда нужно проверять, я бы включил его в функцию. Следуйте принципу СУХОЙ здесь: не повторяйте себя. Еще один полезный совет - это SRP - принцип единой ответственности - делай одно и делай это хорошо.

0 голосов
/ 03 сентября 2010

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

0 голосов
/ 03 сентября 2010

Вариант 2, меньше кода, и это гарантирует, что константа определена, как вы предложили.

...