Когда одиночный элемент на самом деле был бы легче или лучше, чем статический класс? Это кажется мне создающий одиночный элемент, просто дополнительное усилие, это не на самом деле необходимо, но я уверен, что существует серьезное основание. Иначе они не использовались бы, очевидно.
Одна из веских причин для предпочтения синглтона над статическим классом (при условии, что в вашем распоряжении нет лучших шаблонов;)) - это замена одного экземпляра синглтона другим.
Например, если у меня есть такой класс ведения журнала:
public static class Logger {
public static void Log(string s) { ... }
}
public class Client {
public void DoSomething() {
Logger.Log("DoSomething called");
}
}
Он работает очень хорошо, но что, если Logger записывает данные в базу данных или выводит данные на консоль. Если вы пишете тесты, вам, вероятно, не нужны все эти побочные эффекты, но поскольку метод журнала является статическим, вы не можете делать ничего, кроме.
Хорошо, поэтому я хочу выполнить горячую замену моего метода журнала для тестирования. Вперед, гаджет-одиночка!
public class Logger {
private static Logger _instance;
public static Logger Instance
{
get
{
if (_instance == null)
_instance = new Logger();
return _instance;
}
set { _instance = value; }
}
protected Logger() { }
public virtual void Log(string s) { ... }
}
public class Client {
public void DoSomething() {
Logger.Instance.Log("DoSomething called");
}
}
Таким образом, вы можете определить TestLogger: Logger
с пустым методом Log
, а затем установить экземпляр вашего регистратора тестов на экземпляр singleton для тестов. Престо! Вы можете выполнить горячую замену своей реализации регистратора для тестирования или производства, не затрагивая клиентский код.
Синглтоны часто предпочтительнее глобальных переменных, потому что:
РЕДАКТИРОВАТЬ:
Одно интересное использование синглтона в сочетании с фабричным методом можно использовать для создания паттерна Легковес . Это когда вы создаете новый объект, Factory (вместо создания нового объекта) сначала проверяет, чтобы увидеть, что синглтон этого объекта уже создан, если это так, он просто возвращает этот объект, если нет, он создает новый синглтон и возвращает это, отслеживая создаваемые синглтоны. Легковесы работают из-за неизменности синглтона.
Во многих языках статические классы лишены полезных функций, таких как наследование (и полиморфизм в целом).
Несмотря на то, что IMHO шаблон singleton является довольно часто используемым шаблоном, он иногда дает преимущества, такие как:
Синглтоны сохраняют традиционный подход к классам и не требуют повсеместного использования ключевого слова static. Поначалу они могут быть более сложными в реализации, но значительно упростят архитектуру вашей программы. В отличие от статических классов, мы можем использовать синглтоны в качестве параметров или объектов.
Кроме того, вы можете использовать синглтоны с интерфейсами, как и любой другой класс.