Требуется цитата: использование препроцессора - плохая практика - PullRequest
16 голосов
/ 23 января 2009

Я считаю, что использование директив препроцессора, таких как #if UsingNetwork, является плохой практикой ОО - другие коллеги этого не делают. Я думаю, что при использовании контейнера IoC (например, Spring) компоненты могут быть легко настроены, если запрограммированы соответствующим образом. В этом контексте либо контейнер * IoC может установить свойство IsUsingNetwork, либо, если реализация «с использованием сети» ведет себя по-другому, должна быть реализована и внедрена другая реализация этого интерфейса (например: IService, ServiceImplementation, NetworkingServiceImplementation).

Может ли кто-нибудь предоставить цитаты из OO-Gurus или ссылок в книгах , которые в основном гласят "Использование препроцессора - плохая практика OO, если вы пытаетесь настроить поведение, которое должно быть настроено с помощью Контейнер IoC "?

Мне нужны эти цитаты, чтобы убедить сотрудников провести рефакторинг ...

Редактировать: Я знаю и согласен, что использование директив препроцессора для изменения кода, специфичного для целевой платформы, во время компиляции - это хорошо, и именно для этого созданы директивы препроцессора. Однако я думаю, что для получения хорошо спроектированных и тестируемых классов и компонентов следует использовать конфигурацию времени выполнения, а не конфигурацию времени компиляции. Другими словами: использование #defines и # if вне того, для чего они предназначены, приведет к трудностям при тестировании кода и плохо спроектированным классам.

Кто-нибудь читал что-то в этом духе и может дать мне, чтобы я мог сослаться?

Ответы [ 14 ]

1 голос
/ 28 января 2009

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

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

0 голосов
/ 17 августа 2012

Я хотел задать новый вопрос, но, похоже, он здесь подходит. Я согласен, что иметь полноценный препроцессор может быть слишком много для Java. Существует одна явная потребность, которая покрыта преопроцессором в мире C и совсем не покрыта в мире Java: Я хочу, чтобы отладочные распечатки полностью игнорировались компилятором в зависимости от уровня отладки. Сейчас мы полагаемся на «хорошую практику», но на практике эту практику трудно применить, и все же сохраняется некоторая избыточная загрузка ЦП.

В стиле Java, который может быть решен с помощью некоторых назначенных методов, таких как debug (), warning () и т. Д., Для которых вызывается код, генерируется условие.

На самом деле это будет немного интегрировать Log4J в язык.

0 голосов
/ 02 сентября 2011

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

#define A
#undef B
class C
{
#if A
   void F() {}
#else
   void G() {}
#endif
#if B
   void H() {}
#else
   void I() {}
#endif
}

Это приведет к простому

class C
{
   void F() {}
   void I() {}
}

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

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

Microsoft сама использовала множество определений препроцессора в API win32, и вы могли бы знать / помнить ужасное переключение между вызовами методов char и w_char.

Может быть, вам не следует говорить «Не используйте это». Скажите им, «Как использовать это» и «Когда использовать это» вместо этого. Я думаю, что все согласятся с вами, если вы предложите хорошие (более понятные) альтернативы и сможете описать риски, связанные с использованием препроцессорных определений / makros.

Нет необходимости в гуру ... просто будьте гуру. ; -)

0 голосов
/ 29 января 2009

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

...