Назначение синглетонов в программировании - PullRequest
50 голосов
/ 31 марта 2010

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

Для меня это звучит как статический класс. Основное отличие состоит в том, что со статическим классом вы не можете / не можете создавать его экземпляр, вы просто используете его, например, Math.pi(). С одноэлементным классом вам все равно нужно сделать что-то вроде

singleton firstSingleton = new singleton();
firstSingleton.set_name("foo");

singleton secondSingleton = new singleton();

Поправь меня, если я ошибаюсь, но firstSingleton == secondSingleton прямо сейчас, да?

secondSingleston.set_name("bar");
firstSingleton.report_name(); // will output "bar" won't it?

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

Ответы [ 9 ]

52 голосов
/ 31 марта 2010

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

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

Практический пример для хорошего использования синглтона: у вас есть приложение, которое использует базу данных SQL, и вам нужен пул соединений. Целью такого пула является повторное использование соединения с БД, поэтому вы определенно хотите, чтобы все клиенты использовали один и тот же пул. Таким образом, иметь его как синглтон - это правильный дизайн. Но однажды вам понадобится приложение для подключения к второму серверу БД и вы поймете, что у вас не может быть соединений с разными серверами в одном пуле. Таким образом, ваш синглтон «один экземпляр в целом» становится «один экземпляр на сервер БД».

13 голосов
/ 31 марта 2010

почему ты не хочешь

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

Основными причинами являются:

  • Одиночки в основном представляют глобальное состояние (которое является злом).
  • Правильное внедрение зависимостей становится невозможным.

Я предлагаю вам прочитать остальное (включая подробные объяснения) в блоге этого сотрудника Google:

3 голосов
/ 31 марта 2010

Как и другие говорили:

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

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

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

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

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

2 голосов
/ 31 марта 2010

Немного знаний - опасная вещь, а синглтоны - опасные сущности. В дополнение к написанным выше, я могу подчеркнуть, что управление синглтон-объектами в течение всей жизни также важно. В платформе ACE он обрабатывается успешно. Вы можете найти бумагу здесь: http://www.cs.wustl.edu/~schmidt/PDF/ObjMan.pdf

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

2 голосов
/ 31 марта 2010

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

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

0 голосов
/ 31 марта 2010

Есть два способа использования синглетонов.

  1. Как они должны быть использованы. Как правило, с неизменяемыми переменными (C # String.Empty, классы в Smalltalk и т. Д.). Это примерно 1% от использования синглтона.
  2. В качестве замены глобальных переменных. Это плохо. Основной причиной этого являются люди, которые хотят обмениваться общими объектами, не понимая, как правильно использовать Builder. Такое использование Singletons обычно является признаком отсутствия глубокого понимания объектно-ориентированного дизайна.
0 голосов
/ 31 марта 2010

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

0 голосов
/ 31 марта 2010
  1. Singleton - очень полезная замена глобальных переменных, используемых во всем коде.
  2. Синглтоны, как правило, не являются «новыми» или «удаляются» d, они, как правило, инициализируются при первом использовании и удаляются вместе с областью действия программы.
  3. Singletons идеально подходят для упаковки журналов, конфигурации и других классов аппаратного интерфейса.
0 голосов
/ 31 марта 2010

Не во всех языках есть «статические классы» (например, в C ++ их нет).

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

Каждый язык отличается. Я думаю, что в C # они не очень полезны (и, насколько я знаю, они используются не очень часто)

...