Подтвердить что ты не робот

Хорошо, глобальная переменная осуждается, одиночный человек презираем, какая альтернатива?

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

4b9b3361

Ответ 1

Статический класс со статическими элементами данных? Но кого это волнует. Статические члены данных - это всего лишь глобальные переменные с более политически корректной упаковкой.

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

Предполагая, что вы используете C/С++, я бы рекомендовал, чтобы у вас не было глобальных переменных, которые являются экземплярами класса, которые выделяют память из кучи. Они затруднят использование инструментов, которые проверяют утечку памяти. Объявите глобальный как указатель, новый в начале main(), удалите его в конце.

ИЗМЕНИТЬ ПОСЛЕ 6 КОММЕНТАРИЙ: Подумайте о регистрации. Не хотите ли вы написать строку в своем журнале из любого места в вашем приложении? Как конкретно вы достигаете этого, если не будет чего-то глобально видимого для ведения этого журнала? Если вы хотите что-то глобально видимое, тогда сделайте это глобально видимым.

Ответ 2

Ответ зависит от языка. Недавно я познакомился с парнем, чья компания разрабатывает 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

Этот стиль программирования очень похож на методы OO.

Почему лучше, чем глобальные переменные? Нет сюрпризов. Если что-то пошло не так, или вы хотите добавить функцию, вы знаете, что все явно указано в переданных значениях. Более того, вы знаете, что можете подключить множество модулей вместе, и они не будут вмешиваться, если вы явно не передадите состояние между ними. Мой контакт в мобильном телефоне говорит, что это свойство было огромным для его компании - они являются OEM-комплектом программного обеспечения, и они могут легко подключать разные части для разных клиентов.

Мне очень нравится программирование таким образом, потому что я вижу все, что происходит, и мои личные структуры данных защищены от посторонних глаз: -)

Ответ 3

Во-первых, нет смысла делать вид, что синглеты более или менее приемлемы, чем глобалы. Синглтон - это всего лишь глобальный одетый, чтобы выглядеть как ООП. С кучей других проблем, брошенных.

И альтернатива, конечно, не имеет глобальных данных. Вместо того, чтобы ваш класс обращался к некоторой статической (глобальной) переменной где-то, передайте данные в свой конструктор. Да, это означает, что вы должны добавить несколько аргументов в конструктор, но это плохо? Он делает зависимости для класса явным. Я могу протестировать класс, просто предоставив ему разные объекты в конструкторе, тогда как если он опирается на глобальные данные, эти глобальные переменные должны существовать в моем тесте, что является беспорядочным.

Аналогично, я могу легко реорганизовать, потому что нет никаких магических зависимостей от классов, отличных от того, что передавалось непосредственно объекту.

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

Другая общая проблема, как правило, является организационной - трудно понять, где именно данные поступают в большой системе, когда ее можно читать/записывать в любое время. По моему опыту, это больше проблема с разработчиком, чем с самим кодом. Если вы не работаете над одной из этих 200-миллионных мегасистем, которые, как представляется, появляются в основном в книгах по программированию в качестве примеров сложных проблем, вы сможете искать всю свою кодовую базу для определенного элемента достаточно разумно период времени. Следующим шагом является регулярный аудит базы кода, чтобы гарантировать, что глобальные переменные/статические переменные не назначаются случайным образом. Это анафема многих подходов к разработке, но для систем с определенным размером и сложностью это совершенно работоспособное решение.

Ответ 7

Общим решением для этого является использование классов с одним экземпляром вместо одиночных/глобальных переменных.

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

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

Мне было бы безразлично обо всех религиозных войнах об одноэлементном паттерне, хотя - если я думаю, что это соответствует моим потребностям, я вообще используйте его.

Ответ 8

глобальные переменные отлично подходят для небольших программ, но когда они становятся все больше, вы начинаете получать странные побочные эффекты, когда кто-то меняет или исправляет ошибку: "О, я просто установлю этот глобальный, и проблема исчезнет"

Ответ 9

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

  • делает каждую глобальную переменную членом класса. Логически каждая глобальная переменная принадлежит к приложению (или системе). просто создайте класс приложения. определить глобальные объекты как свойства. поэтому они создаются при первом вызове.

  • создать одноэлемент для класса приложения, чтобы вы могли получить доступ к нему по всему миру. Это будет единственный синглтон в вашем коде. ну, в конце это похоже на объекты system.out или system.in в java.

Примечание: я знаю, что это очень старый вопрос, но по-прежнему популярный.