Одной из веских причин для предпочтения синглтона над статическим классом (при условии, что в вашем распоряжении нет лучших образцов;)), является замена одного синглтонного экземпляра другим.
Например, если у меня есть такой класс журналирования:
public static class Logger {
public static void Log(string s) { ... }
}
public class Client {
public void DoSomething() {
Logger.Log("DoSomething called");
}
}
Это работает очень хорошо, но что, если Logger записывает данные в базу данных или выводит вывод на консоль. Если вы пишете тесты, вам, вероятно, не нужны все эти побочные эффекты, но поскольку метод log является статическим, вы ничего не можете сделать, кроме.
Хорошо, я хочу выполнить горячую замену метода журнала для тестирования. Иди иди гаджет синглтон!
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 для тестов. Presto! Вы можете выполнить горячую замену своей реализации логгера для тестирования или производства, не затрагивая клиентский код.