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

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

мне жаль, что это похоже на кандидат на закрытие, если вы не измените его, чтобы сказать, каков ваш q на самом деле

Johannes Schaub - litb 13.12.2008 17:35

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

mhd 13.12.2008 18:36

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

MusiGenesis 13.12.2008 18:42

С другой стороны, это, вероятно, повторяющийся вопрос, но мне нравится ответ Кори, поэтому я оставлю его открытым. :)

MusiGenesis 13.12.2008 18:43

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

Johannes Schaub - litb 13.12.2008 18:57

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

Johannes Schaub - litb 13.12.2008 18:58

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

jalf 13.12.2008 21:30

Я просто ненавижу моды, которые всегда хотят закрыть каждый проклятый вопрос. Где люди могут задавать конкретные повседневные вопросы, если все, что вам нужно, это абстрактный вопрос, на который можно было бы ответить, например, 1 + 1 = 2? Каждый раз я гуглил хороший вопрос, заданный на StackOverFlow, чертовски «закрыто», или «не по теме», или что-то еще!

Louis Hong 15.01.2015 03:42

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

NeoWang 21.04.2017 04:58
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
42
9
18 707
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Ответ принят как подходящий

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

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

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

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

Исходя из .NET, я согласен - статические переменные для классов. Это обеспечивает достаточно хорошую организацию для глобальных переменных. :)

Vilx- 13.12.2008 17:46

Мода? Глобальные переменные осуждались десятилетиями, и по уважительным причинам. Но я согласен с тем, что синглтоны и переменные класса - это одно и то же.

Nemanja Trifunovic 13.12.2008 17:57

Следует отметить, что статические члены на самом деле не решают проблемы, которые представляют глобальные объекты. Причины, по которым глобальные переменные считаются плохими, также в основном относятся к статическим членам.

Mike Burton 13.12.2008 18:51

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

Johannes Schaub - litb 13.12.2008 20:10

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

Mike Burton 13.12.2008 20:21

да, это не причина Только, а причина, по которой они плохие. существуют специфические для языка причины, такие как в C++ порядок построения или разрушения.

Johannes Schaub - litb 13.12.2008 20:41

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

Mike Burton 13.12.2008 21:21

А как насчет регистрации? Какой журнал? В некоторых случаях я определенно хочу, чтобы не был глобальным. Я могу передавать разные журналы разным объектам. У меня могут быть разные экземпляры логов. Раньше я использовал глобальные журналы, что стало серьезной проблемой в приложении, которое мы сделали некоторое время назад.

jalf 13.12.2008 21:27

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

jalf 13.12.2008 21:28

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

Mike Burton 13.12.2008 22:13

Ведение журнала - почти единственное истинное место, где можно разрешить синглтон.

mmcdole 13.12.2008 23:00

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

Corey Trager 15.12.2008 03:34

Что касается плохого «глобального изменяемого состояния», как насчет флага, который регистрирует наличие грязных несохраненных данных, чтобы вы могли запросить пользователя, если он попытается закрыть приложение, что есть несохраненные данные?

Corey Trager 15.12.2008 03:36

Глобалы похожи на GOTO - очень полезные инструменты в руках профессионалов, и их запрет пришел из исторических времен, когда вещи были несопоставимы (например, есть свинину в пустыне без холодильников - и дебаты здесь столь же религиозны).

Lothar 28.08.2016 16:24

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Martin Beckett 13.12.2008 21:30

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

jalf 21.08.2011 18:41

«Альтернативой, конечно же, является отсутствие глобальных данных». Почти для каждой программы характерно иметь какие-то глобальные данные / состояние / единый источник истины.

Konrad 02.10.2019 19:21

Ответ зависит от языка. Недавно я встретил парня, чья компания разрабатывает стек USB, который работает на многих популярных сотовых телефонах (например, чтобы ваш телефон мог разговаривать с вашим компьютером). В их магазине есть правило, согласно которому все процедуры C должны быть реентерабельными. На практике это означает, что вместо глобальных переменных они используют дополнительный параметр для каждой процедуры; параметр указывает на состояние, которое должно сохраняться между подпрограммами.

Я все время использую эту технику для абстракций с состоянием. Пример: абстракция читателя для фотографических изображений: читатель обеспечивает доступ к одному пикселю за раз; он должен знать дескриптор открытого файла, текущую позицию в изображении и т. д. и т. д. Вся эта информация передается в частную структуру 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-производитель программного обеспечения, и они могут легко соединять разные части вместе для разных клиентов.

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

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

Chris Middleton 14.08.2015 23:37

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

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

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

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

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

underscore_d 13.05.2016 12:41

Другие вопросы по теме