Давайте посмотрим правде в глаза. Шаблон Singleton - очень противоречивая тема с ордами программистов по обе стороны забора. Есть те, кто считает, что синглтон - это не более чем прославленная глобальная переменная, а другие придерживаются шаблона и постоянно его используют. Однако я не хочу, чтобы спор синглтонов лежал в основе моего вопроса. Каждый может устроить перетягивание каната, сразиться и посмотреть, кто победит, все, что мне небезразлично . Я пытаюсь сказать, что не верю, что существует единственный правильный ответ, и я не пытаюсь намеренно разжечь партизанские споры. Меня просто интересуют синглтон-альтернативы, когда я задаю вопрос:
Есть ли у них какие-либо конкретные альтернативы шаблону GOF Singleton?
Например, много раз, когда я использовал шаблон singleton в прошлом, меня просто интересовало сохранение состояния / значений одной или нескольких переменных. Однако состояние / значения переменных могут сохраняться между каждым экземпляром класса с использованием статических переменных вместо использования одноэлементного шаблона.
Какие еще у вас есть идеи?
РЕДАКТИРОВАТЬ: Я действительно не хочу, чтобы это был еще один пост о том, «как правильно использовать синглтон». Опять же, я ищу способы избежать этого. Для развлечения, хорошо? Думаю, я задаю чисто академический вопрос голосом вашего лучшего трейлера к фильму: «Что мы могли бы сделать в параллельной вселенной, где нет синглтона?»
источник
Ответы:
Алекс Миллер в « Паттернах, которые я ненавижу » цитирует следующее:
"Когда синглтон кажется ответом, я считаю, что часто разумнее:
источник
Чтобы понять правильный способ обхода синглтонов, вам нужно понять, что не так с синглетонами (и глобальным состоянием в целом):
Синглтоны скрывают зависимости.
Почему это важно?
Потому что, если вы скрываете зависимости, вы теряете из виду степень связи.
Вы можете возразить, что
проще чем
но, по крайней мере, второй API дает понять, кто именно соавторы метода.
Таким образом, способ обхода синглтонов заключается не в использовании статических переменных или локаторов служб, а в преобразовании синглтонов-классов в экземпляры, которые создаются в той области, где они имеют смысл, и внедряются в компоненты и методы, которые в них нуждаются. Вы можете использовать IoC-framework, чтобы справиться с этим, или вы можете сделать это вручную, но важно избавиться от вашего глобального состояния и сделать зависимости и взаимодействия явными.
источник
Лучшее решение, с которым я столкнулся, - это использование фабричного шаблона для создания экземпляров ваших классов. Используя выкройку, вы можете заверить что существует только один экземпляр класса, который используется совместно используемыми объектами.
Я думал, что с этим сложно справиться, но после прочтения этого сообщения в блоге "Куда делись все синглтоны?", это кажется таким естественным. Кроме того, это очень помогает изолировать ваши модульные тесты.
Итак, что вам нужно сделать? Всякий раз, когда объект зависит от другого, он получит его экземпляр только через свой конструктор (в вашем классе нет нового ключевого слова).
А потом фабрика.
Поскольку вы создадите экземпляр своей фабрики только один раз, будет единственный экземпляр exSingleton. Каждый раз, когда вы вызываете buildNeedy, новый экземпляр NeedyClass будет связан с exSingleton.
Надеюсь, это поможет. Пожалуйста, отметьте любые ошибки.
источник
Spring или любой другой IoC-контейнер неплохо справляется с этим. Поскольку классы создаются и управляются вне самого приложения, контейнер может создавать простые классы-одиночки и внедрять их там, где это необходимо.
источник
Вам не нужно изо всех сил стараться избегать шаблонов. Использование выкройки - это либо дизайнерское решение, либо естественная посадка (просто становится на свои места). При разработке системы у вас есть выбор: использовать или не использовать шаблон. Однако вы не должны изо всех сил избегать всего, что в конечном итоге является выбором дизайна.
Я не избегаю паттерна Singleton. Либо это уместно, и я им пользуюсь, либо не уместно, и я им не пользуюсь. Я считаю, что это так просто.
Пригодность (или ее отсутствие) синглтона зависит от ситуации. Это проектное решение, которое необходимо принять, и последствия этого решения должны быть поняты (и задокументированы).
источник
Monostate (описанный в книге Роберта Мартина «Гибкая разработка программного обеспечения») является альтернативой singleton. В этом шаблоне все данные класса статичны, но геттеры / сеттеры нестатичны.
Например:
Monostate имеет поведение, подобное синглтону, но делает это таким образом, что программист не обязательно осведомлен о том, что используется синглтон.
источник
Одноплодная картина существует потому , что существует ситуации , когда один объект необходим для обеспечения набора услуг .
Даже если это так, я все же считаю подход создания одиночных экземпляров с использованием глобального статического поля / свойства, представляющего экземпляр, неуместным. Это неуместно, поскольку создает зависимость в коде между статическим полем и объектом, а не услугами, которые предоставляет объект.
Поэтому вместо классического шаблона синглтона я рекомендую использовать шаблон службы «подобный» с обслуживаемыми контейнерами , где вместо использования синглтона через статическое поле вы получаете ссылку на него с помощью метода, запрашивающего тип требуемой службы.
вместо единого глобального
Таким образом, если вы хотите изменить тип объекта с одноэлементного на что-то еще, у вас будет несложно сделать это. Также в качестве дополнительного преимущества вам не нужно передавать выделение экземпляров объекта каждому методу.
Также см. Инверсия управления , идея состоит в том, что, открывая синглтоны напрямую для потребителя, вы создаете зависимость между потребителем и экземпляром объекта, а не сервисами объекта, предоставляемыми объектом.
Мое мнение - по возможности скрывать использование одноэлементного шаблона, потому что его не всегда можно или желательно избежать.
источник
Если вы используете Singleton для представления одного объекта данных, вы можете вместо этого передать объект данных в качестве параметра метода.
(хотя я бы сказал, что это неправильный способ использования синглтона в первую очередь)
источник
Если ваша проблема в том, что вы хотите сохранить состояние, вам нужен класс MumbleManager. Перед тем как вы начнете работать с системой, ваш клиент создает MumbleManager, где Mumble - это имя системы. Благодаря этому сохраняется состояние. Скорее всего, ваш MumbleManager будет содержать пакет свойств, в котором хранится ваше состояние.
Этот тип стиля выглядит очень похожим на C, а не на объектный - вы обнаружите, что все объекты, которые определяют вашу систему, будут иметь ссылку на один и тот же MumbleManager.
источник
Используйте простой объект и объект фабрики. Фабрика отвечает за контроль экземпляра и деталей простого объекта только с информацией о конфигурации (например, она содержит) и поведением.
источник
На самом деле, если вы разрабатываете с нуля, избегая синглтонов, вам, возможно, не придется обходиться без синглтонов с помощью статических переменных. При использовании статических переменных вы также более или менее создаете синглтон, с той лишь разницей, что вы создаете разные экземпляры объектов, однако внутренне все они ведут себя так, как если бы они использовали синглтон.
Можете ли вы привести подробный пример, где вы используете синглтон или где в настоящее время используется синглтон, и вы пытаетесь его избежать? Это могло бы помочь людям найти более изящное решение, как справиться с ситуацией вообще без синглтона.
Кстати, у меня лично нет проблем с синглтонами, и я не могу понять проблемы, которые есть у других людей в отношении синглтонов. Я не вижу в них ничего плохого. То есть, если вы ими не злоупотребляете. Любой полезной техникой можно злоупотреблять, и злоупотребление приведет к отрицательным результатам. Другой способ, которым часто злоупотребляют, - это наследование. Тем не менее, никто не скажет, что наследование - это что-то плохое только потому, что некоторые люди ужасно злоупотребляют им.
источник
Лично для меня гораздо более разумный способ реализовать что-то, что ведет себя как синглтон, - это использовать полностью статический класс (статические члены, статические методы, статические свойства). Большую часть времени я реализую это таким образом (я не могу думать о каких-либо различиях в поведении с точки зрения пользователя)
источник
Я думаю, что лучшее место для контроля синглтона - это уровень дизайна класса. На этом этапе вы должны иметь возможность наметить взаимодействия между классами и увидеть, действительно ли что-то абсолютно, определенно требует, чтобы только 1 экземпляр этого класса когда-либо существовал в любой момент жизни приложения.
Если это так, то у вас есть синглтон. Если вы добавляете синглтоны для удобства во время кодирования, тогда вам действительно стоит пересмотреть свой дизайн, а также прекратить кодирование указанных синглтонов :)
И да, я имел в виду слово «полиция», а не «избегать». Одноэлементного элемента не следует избегать (точно так же, как нельзя избегать goto и глобальных переменных). Вместо этого вам следует контролировать его использование и убедиться, что это лучший способ эффективно выполнить то, что вы хотите.
источник
Я использую синглтон в основном как «контейнер методов», вообще без состояния. Если мне нужно поделиться этими методами со многими классами и я хочу избежать бремени создания экземпляров и инициализации, я создаю контекст / сеанс и инициализирую все классы там; все, что относится к сеансу, также имеет доступ к содержащемуся в нем «синглтону».
источник
Поскольку я не программировал в объектно-ориентированной среде (например, Java), я не совсем разбираюсь в тонкостях дискуссии. Но я реализовал синглтон в PHP 4. Я сделал это как способ создания обработчика базы данных «черного ящика», который автоматически инициализируется и не требует передачи вызовов функций вверх и вниз в неполной и несколько сломанной структуре.
Прочитав несколько ссылок на шаблоны синглтонов, я не совсем уверен, что реализовал бы его таким же образом снова. Что действительно было нужно, так это несколько объектов с общим хранилищем (например, фактический дескриптор базы данных), и это практически то, во что превратился мой вызов.
Как и большинство шаблонов и алгоритмов, использование синглтона «просто потому, что это круто» - это неправильная вещь. Мне нужен был действительно вызов «черного ящика», который оказался бы очень похожим на синглтон. И ИМО, это способ решить вопрос: не забывайте о шаблоне, но также смотрите на его более широкий охват и на том, на каком уровне его экземпляр должен быть уникальным.
источник
Что ты имеешь в виду, как я могу этого избежать?
Чтобы «избежать» этого, это подразумевает, что есть много ситуаций, с которыми я сталкиваюсь, в которых одноэлементный шаблон хорошо подходит, и, следовательно, я должен принять некоторые меры, чтобы разрядить эти ситуации.
Но нет. Мне не нужно избегать одноэлементного шаблона. Этого просто не возникает.
источник