Синглтоны дают вам возможность комбинировать две плохие черты в одном классе. Это неправильно почти во всех отношениях.
Синглтон дает вам:
- Глобальный доступ к объекту и
- Гарантия того, что не может быть создано более одного объекта этого типа
Номер один прост. Глобалы вообще плохие. Мы никогда не должны делать объекты глобально доступными, если нам действительно это не нужно.
Номер два может звучать так, как будто это имеет смысл, но давайте подумаем об этом. Когда в последний раз вы ** случайно * создавали новый объект вместо ссылки на существующий? Поскольку это тег C ++, давайте использовать пример из этого языка. Вы часто случайно пишете
std::ostream os;
os << "hello world\n";
Когда вы намеревались написать
std::cout << "hello world\n";
Конечно нет. Нам не нужна защита от этой ошибки, потому что такого рода ошибки просто не происходят. Если да, то правильным ответом будет пойти домой и поспать 12-20 часов и надеяться, что тебе станет лучше.
Если нужен только один объект, просто создайте один экземпляр. Если один объект должен быть глобально доступен, сделайте его глобальным. Но это не значит, что нельзя создавать другие экземпляры.
Ограничение «возможен только один экземпляр» на самом деле не защищает нас от возможных ошибок. Но это действительно делает наш код очень сложным для рефакторинга и сопровождения. Потому что довольно часто мы узнаем позже , что нам нужно более одного экземпляра. У нас do имеется более одной базы данных, у нас do имеется более одного объекта конфигурации, нам нужно несколько регистраторов. Наши модульные тесты могут захотеть создавать и воссоздавать эти объекты каждый тест, чтобы взять общий пример.
Таким образом, синглтон должен использоваться тогда и только тогда, когда нам нужны оба признаков, которые он предлагает: Если нам нужен глобальный доступ (что редко, потому что глобальные списки обычно не рекомендуется) и нам нужно , чтобы никто не смог когда-либо создать более одного экземпляра класса (что звучит для меня как проблема дизайна). Единственная причина, по которой я это вижу, заключается в том, что создание двух экземпляров повредит нашему состоянию приложения - возможно, потому, что класс содержит несколько статических членов или аналогичную глупость. В этом случае очевидный ответ - исправить этот класс. Это не должно зависеть от того, чтобы быть единственным экземпляром.
Если вам нужен глобальный доступ к объекту, сделайте его глобальным, например std::cout
. Но не ограничивайте количество экземпляров, которые могут быть созданы.
Если вам абсолютно необходимо ограничить количество экземпляров класса одним, и нет никакого способа, которым создание второго экземпляра можно было бы безопасно обработать, тогда примените это. Но не делайте это глобально доступным.
Если вам нужны обе эти черты, то 1) сделайте их синглтоном и 2) дайте мне знать, для чего вам это нужно, потому что мне трудно представить такой случай.