Что так плохо про синглтоны?

В паттерн Singleton представляет собой полностью оплачены участником Гофкнига узоры, но он в последнее время выглядит довольно сиротски мире разработчика. Я до сих пор использую довольно много одиночек, особенно для классы фабрики, и в то время как вы должны быть немного осторожным о многопоточности вопросы (как и любой класс на самом деле), я не понимаю, почему они так ужасны.

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

Пожалуйста, поддержите свои ответы с &quotФакты, ссылки, или конкретные знанияи";

Комментарии к вопросу (24)
Решение

Перефразировано от кнопки Брайан:

  1. Они обычно используются в качестве глобального экземпляра, почему это так плохо? Потому что вы скрываете зависимости вашего приложения в код, вместо того, чтобы обнародовать их через интерфейсы. Делая что-то глобальное, чтобы не передать его вокруг код.

  2. Они нарушают единый принцип ответственности: в силу того, что они контролируют свои собственные творения и жизненного цикла.

  3. Они, по сути, привести код, который будет плотно в сочетании. Это делает подтасовывая их под тест, а во многих случаях сложно.

  4. Они несут вокруг для жизни приложения. Еще один хит для тестирования, так как вы можете в конечном итоге с ситуацией, когда тесты должны быть заказаны, который является большой нет нет для модульных тестов. Почему? Ведь каждый испытательный блок должен быть независимым от других.

Комментарии (22)

Синглтоны решить одну (и только одну) проблему.

Конфликты Ресурсов.

Если у вас есть некоторый ресурс, который

(1) может иметь только один экземпляр, и

(2) нужно управлять, что один экземпляр,

вам нужен одноэлементные.

Нет'т много примеров. Лог-файл большой. Вы Don'т хочу оставить один файл журнала. Вы хотите флеш, синхронизация и закрыть его должным образом. Это пример один общий ресурс, который должен быть управляемым.

Это's редкие, что вам нужен синглтон. Почему они'вновь все плохо, что они чувствуют себя как глобальный, и они&#39 полностью оплачен членом Гоф шаблоны проектирования; повторное книга.

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

Комментарии (23)

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

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

Комментарии (8)

Мисько Hevery, от Google, имеет некоторые интересные статьи на эту тему...

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

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

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

Комментарии (7)

Я думаю, что путаница вызвана тем, что люди Дон'т знать реальное применение шаблона Singleton. Я могу'т подчеркнуть это достаточно. Синглтон-это не шаблон для обруча глобалс. Одноэлементный шаблон должен только использоваться, чтобы гарантировать, что один и только один экземпляр данного класса существует во время выполнения.

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

Комментарии (11)

Один довольно плохо про синглтоны, что вы можете'т очень легко расширить их. Вы в основном должны строить какие-то шаблон "декоратор" или что-то подобное, если вы хотите изменить свое поведение. Также, если один день вы хотите иметь несколько способов делать что-то одно, он может быть довольно болезненным, чтобы изменить, в зависимости от того, как вы выложите свой код.

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

Так в основном:

public MyConstructor(Singleton singleton) {
    this.singleton = singleton;
}

а не:

public MyConstructor() {
    this.singleton = Singleton.getInstance();
}

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

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

Комментарии (7)

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

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

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

Существует также многопоточные сценарии, где синглтоны могут стать узким местом, а также проблемы с синхронизацией.

Комментарии (3)

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

Комментарии (6)

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

Рассмотрим следующую ситуацию: как разработчик, вы должны создать веб-приложение, которое обращается к базе данных. Для обеспечения одновременных обращений к базе данных не конфликтуют друг с другом, вы создаете тему-сохранения SingletonDao`:

public class SingletonDao {
    // songleton's static variable and getInstance() method etc. omitted
    public void writeXYZ(...){
        synchronized(...){
            // some database writing operations...
        }
    }
}

Так вы уверены, что существует только один синглтон в вашем приложении и все базы пройти через это один, и только SingletonDao`. Производственной среды теперь выглядит так:

Все нормально до сих пор.

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

Это звучит странно, но теперь у вас есть много синглтонов в приложении. И это именно то, что синглтон не должен: иметь много объектов это. Это особенно плохо, если вы, как показано в этом примере, хочу сделать синхронизированные вызовы к базе данных.

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

Комментарии (2)
  1. Это легко (АБ)используется как глобальная переменная.
  2. Классы, которые зависят от синглтоны-это сравнительно труднее модульного тестирования в изоляции.
Комментарии (0)

Монополия-это дьявол и одиночек с не-чтения/изменяемое состояние-это 'и#39; проблемы...

После прочтения синглтоны-это патологические вруны, Как предложено в Джейсон'ы ответ я пришел через эту "утку", что предоставляет лучшие представлен пример как синглтоны часто неправильно.

Global-это плохо, потому что:

  • это. Это вызывает конфликт имен
  • б. Он предоставляет государство в неоправданные мода

когда дело доходит до синглтоны

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

В последнем заявлении он'ы со ссылкой на блог'с понятием 'синглтоны лжецы'.

Каким образом это относится к монополии?

Чтобы начать игру в монополию, в первую очередь:

  • мы устанавливаем правила первого, так что все на той же странице
  • всем дается равный старт в начале игры
  • только один набор правил, чтобы избежать путаницы
  • правила Не'т позволил изменить на протяжении всей игры

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

Так что вы'вновь играть в Монополию с друзьями Боб, Джо и Эд. Вы'вновь стремительно строить свою империю и отнимает долю рынка в геометрической прогрессии. Ваши противники ослабления и вы начинаете запах крови (образно). Твой приятель Боб положил все свои деньги в gridlocking как можно больше малоценные свойства, но его это'т получать высокую отдачу от инвестиций, как он ожидал. Боб, как удар судьбы, оказывается на набережной и вырезали из игры.

Теперь игра идет от дружественных кости прокатки для серьезного бизнеса. Боб был сделан пример провала и Джо и Эд Дон'т хотите в конечном итоге, как 'тот парень'. Поэтому, будучи ведущим игроком, ты, вдруг, стал врагом. Джо и Эд начать практиковать под столом руки, за деньги уколы, недооцененной дома замена и вообще ничего, чтобы ослабить вас, как игрока, пока один из них поднимается наверх.

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

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

Как это относится к программированию?

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

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

Одноэлементный только если вам нужна какая синглтон обеспечивает. Записи-один только для чтения экземпляра объекта. Это же правило следует каскад на объект's свойства/членами.

Комментарии (3)

Синглтон не об одном экземпляре!

В отличие от других ответов я не'т хотите поговорить о том, что случилось с одиночек, но, чтобы показать вам, насколько мощным и удивительным, когда они используются правильно!

  • Проблема: Синглтон может быть проблемой в многопоточные среды Раствор: использовать один процесс резьбовое ушко, чтобы инициализировать все зависимости от вашего синглтон.
  • Проблема: трудно глумиться одиночек. Решение: способ применения Фабрика шаблон для глумления MyModel myModel = Фабрика.вкачать(MyModel.class); Вы можете карту MyModel до TestMyModel класс, который наследует его, везде, когда MyModel будет впрыснут вы получите TestMyModel instread.
  • Проблема: синглтонов может привести к утечке памяти, поскольку они никогда не удаляются. Решение: ну, не выбрасывайте их! Реализации обратного вызова в вашем приложении правильно распоряжаться синглтоны, вы должны удалить любые сведения, связанные с ними и, наконец, удалить их с завода.

Как я заявил в названии синглтон не об одном экземпляре.

  • Синглтоны улучшает читаемость: вы можете посмотреть на свой класс и посмотреть, что синглтон это вводят, чтобы выяснить, что это'ы зависимостей.
  • Синглтоны улучшает обслуживание: после того, как вы убрали зависимости от класса, вам просто удалил некоторые синглтон инъекции, вы не'т должны пойти и изменить большую ссылку из других классов, которые просто перенесли свою зависимость вокруг(это вонючий код для меня @Джим Бургер)
  • Одноплодной беременности улучшает память и производительность: когда какая-то вещь происходит в вашей программе, и он занимает длинную цепочку обратных вызовов поставить, ты тратишь памяти и производительности, с помощью Одноэлементного вы средний человек, и повысить производительность вашей системы и памяти(избегая ненужных локальных переменных назначений).
Комментарии (3)

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

Два больших винта окна я вижу: рассматривая ее как глобальную & неспособность определить одноэлементный закрытия.

Все говорят о Singleton's в качестве глобальных переменных, потому что они в основном являются. Однако, много (к сожалению, не все) зло в глобальном приходит не свойственно быть глобальной, но как вы его используете. То же касается синглтонов. На самом деле больше, так как "один экземпляр-то" совсем не'т нужно иметь в виду, что "глобально" по. Это более естественный побочный продукт, и учитывая все плохое, что мы знаем, исходит от него, мы должны'т быть в спешке, чтобы использовать глобальную доступность. После того как программисты видят одноэлементный они, кажется, всегда получить доступ к нему напрямую через его метод экземпляра. Вместо этого, вы должны перейти к его так же, как и любой другой объект. Большая часть кода должна'т даже знайте, что он имеет дело с Синглтон (свободная связь, верно?). Если только небольшой кусок кода получает доступ к объекту, как это глобальная, много вреда отменено. Я рекомендую его применением путем ограничения доступа к функции экземпляра.

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

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

Если вам не допускать тех ошибок, одиночек еще можно лаваш, немного он готов увидеть много страшных проблем значительно сглаживается. Представьте, что Java синглтон, который явно определен как раз на classloder (что означает, что он должен какой-нить политики безопасности), с определенными созидания и разрушения методы и жизненного цикла, что диктует, когда и как они вызываются, и чей-то "экземпляр" и метод пакет защиты так это, как правило, осуществляется через другие, не глобальные объекты. Еще одним потенциальным источником неприятностей, но, конечно, гораздо меньше проблем.

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

Комментарии (0)

в <а href="и http://en.wikipedia.org/wiki/Singleton_pattern">Смотри Singleton_pattern Википедии</а>

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

Ссылки (только соответствующие ссылки из статьи)

  1. ^ Алексей Миллер. в <а href="и http://tech.puredanger.com/2007/07/03/pattern-hate-singleton/">узоры ненавижу #1: Синглтон</а> июль 2007
  2. ^ Скотт Денсмор. в <а href="и http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx">почему одиночки такие злые</а>, май 2004
  3. ^ Стив Yegge. в <а href="и http://steve.yegge.googlepages.com/singleton-considered-stupid">синглтоны считать глупо</а> сентябрь 2004 г.
  4. Б. ^ Ж. Rainsberger, компании IBM. в <а href="и http://www-128.ibm.com/developerworks/webservices/library/co-single.html">использовать синглтоны мудро</а> в июле 2001 года
Комментарии (2)

Это's не то, что одиночки сами по себе плохо, но шаблон проектирования GoF является. Единственный аргумент, который реально действует является то, что шаблон проектирования не'т предоставить в отношении тестирования, особенно, если тесты запускаются параллельно.

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

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

  2. Убедитесь, что Синглтон является потокобезопасным. Что'с данной.

  3. Синглтон должен быть простым и не слишком сложным.

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

  5. Во время тестирования и обеспечения детерминированного поведения, создать одноэлементный класс как отдельный экземпляр, так как либо сам класс или заглушки/макет, который реализует его поведение, и передать его как к классу, которому он требуется. Дон'т использовать классовый фактор, который создает этот объект под тест, который должен синглетона в ходе теста, как будет проходить единый глобальный экземпляр, который побеждает цель.

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

Комментарии (1)

Я'd, как решить 4 очка в принятой ответ, надеюсь, кто-нибудь может объяснить, почему я'м неправильно.

  1. Почему скрывается зависимостей в коде плохо? Существуют уже десятки скрытых зависимостей (c времени выполнения вызовов API ОС вызовы, глобальные вызовы функций), и зависимости синглтон легко найти (поиск например, ()).

"Изготовление чего-то глобального, чтобы не передать его вокруг запах кода." Почему так'т проезжает что-то вокруг, чтобы избежать синглтон запах код?

Если вы'повторного прохождения объекта через 10 функций в стеке вызовов только чтобы избежать синглтоном, это так здорово?

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

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

  3. Почему это изменение, как долго длится состояние? Синглтоны могут быть созданы или уничтожены вручную, так что контроль все же есть, и вы можете принять всю жизнь такой же, как не-объект-синглтон'ы жизни будет.

Что касается юнит-тестов:

  • не все классы должны быть полностью испытания
  • не все классы, которые должны быть полностью тестирование нужно менять реализация синглтона
  • если они до должны быть полностью протестированы и нужно изменить реализацию, это's легкий для того чтобы изменить класс от с помощью одноэлементного к синглтон прошли через зависимость инъекции.
Комментарии (12)

Винс Хьюстон эти критерии, который кажется мне разумным:

Синглтон должна рассматриваться только если все три из следующих критериев:

  • право собственности на один экземпляр не может быть разумно приписан
  • отложенная инициализация желательно
  • глобальный доступ не предусмотрено иное

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

Комментарии (0)

Синглтоны-это плохо с точки зрения пуриста.

С точки практической зрения, одноэлементный компромисс развивающееся время против сложности.

Если вы знаете, ваша заявка выиграла't изменить то, что они довольно хорошо пойти. Просто знаю, что вы, возможно, потребуется рефакторинг вещи, если ваши требования меняются неожиданным образом (что довольно хорошо в большинстве случаев).

Иногда используются также усложняют тестирование.

Комментарии (3)

Я'м не собираюсь комментировать хороший аргумент/зло, но я не'т использовать их с Весна пришли вместе. Используя внедрение зависимостей в значительной степени удалены мои требования к синглтон, servicelocators и фабрик. Я нахожу это гораздо более продуктивным и спокойным окружением, по крайней мере для такого типа работы мне делать (на основе Java Web-приложений).

Комментарии (3)

Нет ничего неотъемлемо неправильно с рисунком, если он используется для какой-то аспект вашей модели, которая действительно одинока.

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

Комментарии (2)