Делайте интерфейсы явными
Причина
Корректность. Допущения, не указанные в интерфейсе, легко упустить из виду и трудно протестировать.
Пример (плохой)
Управление поведением функции через глобальную (пространство имён) переменную (режим вызова) является неявным и потенциально вводящим в заблуждение. Например:
int round(double d)
{
return (round_up) ? ceil(d) : d; // не делайте так: «невидимая» зависимость
}
Вызывающей стороне будет неочевидно, что два вызова round(7.2) могут дать разные результаты.
Исключение
Иногда мы управляем деталями набора операций через переменную среды, например, обычный или подробный вывод, отладочный или оптимизированный. Использование нелокального управления потенциально вводит в заблуждение, но управляет только деталями реализации иначе фиксированной семантики.
Пример (плохой)
Отчётность через нелокальные переменные (например, errno) легко игнорировать. Например:
// не делайте так: нет проверки возвращаемого значения fprintf
fprintf(connection, "logging: %d %d %d
", x, y, s);
Что если соединение оборвётся и вывод в журнал не будет произведён? Смотрите I.???.
Альтернатива: Бросьте исключение. Исключение нельзя проигнорировать.
Альтернативная формулировка: Избегайте передачи информации через интерфейс через нелокальное или неявное состояние. Обратите внимание, что не-const функции-члены передают информацию другим функциям-членам через состояние своего объекта.
Альтернативная формулировка: Интерфейс должен быть функцией или набором функций. Функции могут быть шаблонами функций, а наборы функций могут быть классами или шаблонами классов.
Контроль
- (Простой) Функция не должна принимать решения о потоке управления на основе значений переменных, объявленных в области пространства имён.
- (Простой) Функция не должна записывать в переменные, объявленные в области пространства имён.