Какое конкретное законное использование для одиночек?

Возможный дубликат:
На шаблонах проектирования: когда использовать Singleton?

Этот вопрос не касается того, считаются ли в одиночку одиночные игры "вредоносными". Я просто хочу узнать, по вашему опыту, какие КОНКРЕТНЫЕ СИТУАЦИИ, в которых синглеты, похоже, работают хорошо.

EDIT: Пожалуйста, если вы хотите обсудить уместность и/или злость одиночных синглов вообще, возникают вопросы, связанные с aleady: 137975, 11831

Oops! Я только что обнаружил, что мой вопрос уже задан здесь: На шаблонах проектирования: когда использовать Singleton?

Ответ 1

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

Ответ 2

Расширение моего комментария...

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

  • Глобальная переменная является глобальной переменной.

    Как только вы используете

    void f() { X* x = X::getInstance(); ... }

    вместо void f(X*), ваш заказ на блюдо для спагетти принято.

  • Синглтоны размножаются и любят зависеть друг от друга. SessionManager использует EventManager, который использует LogManager. Кто-то хочет, чтобы в файлах журналов указывалось имя текущего пользователя. Поддерживающий LogManager добавляет SessionManager::getInstance()->getUser()->getName();, все розы до LoginManager, который также использует LogManager, хочет зарегистрировать сбой входа.

  • Синглоты препятствуют тестируемости.

    Свойство single-instance полуполезно только в производственном коде. Возможно, вам не удастся проверить функцию void f() и, вероятно, будет (несколько) проверять только на счастливый путь.

Как вы можете догадаться, мой ответ на вопрос, когда глобальные переменные хороши? никогда". Что твой?

Ответ 3

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

Ответ 4

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

Ответ 5

  • Logging.

  • Поиск локализованных строковых ресурсов, например. Strings.get("CONFIRM_DELETE").

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

Ответ 6

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

Я по-прежнему считаю, что следует избегать одиночных игр (по крайней мере, на Java).

Здесь есть две разные вещи: концепция и механизм для принудительного применения шаблона Singleton.

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

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

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

Ответ 7

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

Моя ситуация заключалась в том, что у меня был API, который построил одноэлементные объекты для обработки таких функций управления, как Security, Configuration и т.д. API использовал EntityFramework, а также вытащил PlugIns (используя MEF). Поскольку построение этих классов не всегда выполнялось моим кодом (особенно для объектов EF), не всегда можно было вставлять их в объекты biz элегантно. Поэтому я использовал синглтоны, к которым можно получить доступ в любом месте объекта проекта, охватывающего весь спектр.

Ответ 8

Главный сервер принимает запросы от клиентов и передает эти запросы в подчиненный процесс. Подчиненный процесс может использовать singleton для связи с главным сервером.

Ответ 9

Я стараюсь не полагаться на Синглтон, однако я предпочитаю развязку, чтобы не использовать Singleton. Таким образом, я часто использую Singleton в сочетании с шаблоном Prototype, который позволяет регистрировать прототипы при загрузке библиотеки (создание глобальных объектов).

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

Использование Singleton для карты позволяет мне полностью развязать код. Никакая библиотека не зависит от моей сервисной библиотеки, никакая строка кода вне моей сервисной библиотеки не имеет права регистрировать ее службу. Фактически, я могу решить, какие службы внедряются просто путем изменения моей команды "link" во время компиляции: если я не связываюсь с библиотекой, ее служба не внедрена.

Я действительно нахожу это полезным там... для настройки и, таким образом, я предпочитаю использовать MonoPattern: т.е. класс нормального вида со всеми экземплярами, использующими одни и те же данные (таким образом, обертывая реальный синглтон). Делает более легкую миграцию на случай, если это необходимо, так как клиенты не знают, что используют таймер Oneton.

Ответ 10

В дополнение к протоколированию (как уже упоминалось в большинстве других случаев), я использовал синглеты для контейнеров Inversion of Control (IoC). Зависимости регистрируются один раз в начале приложения, и можно разрешить зависимость в любой момент времени в приложении, используя метод singleton.

Ответ 11

Они хороши для предметов, которые вы хотите рассматривать как уникальные ресурсы.

В качестве примера в веб-системах вы можете использовать только одно соединение с базой данных для каждой страницы, которая служила - в этом случае использование шаблона singleton имеет смысл. (Хотя вам придется кодировать знание о том, что объект доступа к базе данных был одноэлементным, что является менее идеальным, но приемлемым, если оно четко документировано и т.д.)

Ответ 12

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