Ответ зависит от языка. Недавно я встретил человека, чья компания разрабатывает USB-стек, который работает на многих популярных мобильных телефонах (например, чтобы ваш телефон мог общаться с вашим компьютером). В их магазине есть правило, что все процедуры на С должны быть реентерабельными. На практике это означает, что вместо глобальных переменных они используют дополнительный параметр для каждой процедуры; параметр указывает на состояние, которое должно сохраняться между подпрограммами.
Я использую эту технику все время для абстракций с состоянием. Пример: абстракция ридера для фотографических изображений: ридер обеспечивает доступ к одному пикселю за раз; он должен знать дескриптор открытого файла, текущую позицию на изображении и так далее. Вся эта информация входит в частную структуру C или в закрытые члены класса C ++. Нет глобальных переменных. Внешний мир видит:
typedef struct Pnmrdr_T *Pnmrdr_T;
struct Pnmrdr_T *Pnmrdr_new(FILE *);
pixel Pnmrdr_get(Pnmrdr_T);
void Pnmrdr_close(Pnmrdr_T);
void Pnmrdr_free(Pnmrdr_T *rp); // frees memory and sets *rp = NULL
Этот стиль программирования очень похож на методы ОО.
Почему лучше, чем глобальные переменные? Сюрпризов нет . Если что-то идет не так или вы хотите добавить функцию, вы знаете, что все явно указано в передаваемых значениях. Более того, вы знаете, что вы можете подключить множество модулей вместе, и они не будут мешать, если вы явно не передадите состояние между ними. Мой контакт в бизнесе по мобильному телефону говорит, что это свойство имело огромное значение для его компании - они являются программным обеспечением OEM-производителя и могут легко объединять разные компоненты для разных клиентов.
Мне действительно нравится программировать таким образом, потому что я вижу все, что происходит, и мои частные структуры данных защищены от посторонних глаз: -)