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

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

13.12.2008 14:32:21
Мне жаль, что это похоже на кандидатуру на закрытие, если только вы не измените его, чтобы сказать, что вы на самом деле делаете
Johannes Schaub - litb 13.12.2008 14:35:49
Я что-то не так напечатал? Извините, я не понимаю, почему вы хотите закрыть эти вопросы. Все, что я спрашивал, было просто общим вопросом программирования.
mhd 13.12.2008 15:36:26
Я думаю, что ваш вопрос в порядке. Если вы не читаете это очень внимательно, это кажется немного воинственным (слова типа «осуждаемый» и «презираемый» производят этот эффект), но вы действительно просто спрашиваете о передовых методах.
MusiGenesis 13.12.2008 15:42:35
С другой стороны, это, вероятно, дублирующий вопрос, но мне нравится ответ Кори, поэтому я оставлю его открытым. :)
MusiGenesis 13.12.2008 15:43:32
Литб: Я думаю, что большинство людей должны согласиться с одиночками. Они просто глобальные, с добавленными дополнительными трудностями. Если вам нужно использовать глобальные данные, просто сделайте их глобальными. Нет смысла настаивать на добавлении дополнительных фальшивых требований, таких как «единый экземпляр», что на практике никогда не соответствует действительности.
jalf 13.12.2008 18:30:50
9 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

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

36
13.12.2008 18:13:31
Исходя из .NET я согласен - статические переменные для классов. Это обеспечивает достаточно хорошую организацию для вас глобальных переменных. :)
Vilx- 13.12.2008 14:46:29
Следует отметить, что статические члены на самом деле не решают проблем, которые представляют глобальные переменные. Причины, по которым глобальные переменные рассматриваются как плохие, также в основном относятся к статическим элементам.
Mike Burton 13.12.2008 15:51:54
нет. глобалы видятся как плохие из-за их яркого охвата. но это не относится ни к другим свободным объектам в неглобальном пространстве имен, ни к статическим членам класса
Johannes Schaub - litb 13.12.2008 17:10:34
Но, конечно, иногда вам может понадобиться глобальный журнал. Вот почему я чувствую, что не глобальные как таковые являются плохими, а глобальное изменчивое состояние . Журнал может быть глобальным, если это не изменяемое состояние. Если он просто берет текст и выбрасывает его на какой-то внешний носитель, это нормально. Но не все журналы так просты
jalf 13.12.2008 18:28:22
Что касается «Ведение журнала - почти единственное истинное место, которое должен быть разрешен Singleton», как насчет конфигурации? Я имею в виду получение настроек из файла конфигурации? Приложение читает / загружает файл при запуске, а затем делает значения читаемыми из любой точки приложения.
Corey Trager 15.12.2008 00:34:04

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

2
13.12.2008 14:48:39

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

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

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

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

0
13.12.2008 15:32:14

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

3
13.12.2008 15:37:17

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

-1
13.12.2008 15:47:54

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

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

1
13.12.2008 15:50:05

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

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

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

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

8
4.09.2011 09:02:24
Вы хотите передать экземпляр журнала каждой функции, или языку пользователя, или местоположению файла справки, чтобы он мог выполнять контекстно-зависимую помощь.
Martin Beckett 13.12.2008 18:30:10
может быть. Это зависит. Это альтернатива, но это не единственный вариант. Но если для каждой функции нужен пользовательский язык или местоположение файла справки, то кажется, что у вас есть большие проблемы в вашей кодовой базе, о которых нужно беспокоиться. Мне лично (обычно) хорошо с регистраторами как глобальными, потому что они не влияют на ход программы. Но я не доверяю изменчивому глобальному состоянию.
jalf 21.08.2011 14:41:17
«И альтернатива, конечно, не иметь глобальных данных». Практически во всех программах есть какие-то глобальные данные / состояние / единый источник правды.
Konrad 2.10.2019 16:21:00

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

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

17
13.12.2008 19:41:43
ИМО этот ответ намного лучше, чем принятый, потому что он дает альтернативу глобальным. Передача данных почти всегда более понятна, даже если это немного увеличивает количество параметров. Спасибо за ваше понимание.
Chris Middleton 14.08.2015 20:37:18

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

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

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

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

0
23.02.2016 13:57:00
Можете ли вы объяснить, почему, если вообще, такой синглтон действительно лучше, чем глобальные? Синглтоны часто (обычно?) Просто запутанный способ запутать тот факт, что вы все еще используете глобальное состояние. Я предполагаю, что вы подразумеваете, что можно инкапсулировать переменные в объекте с помощью методов получения / установки, но это не ясно. Даже в этом случае люди склонны утверждать, что нет никакой реальной необходимости обеспечивать его единственность через все шаблоны, которые требует шаблон; просто не создавайте его более одного раза.
underscore_d 13.05.2016 09:41:25