Статичні класи прекрасні, якщо вони використовуються в потрібних місцях.
А саме: Методи, які є «листовими» методами (вони не змінюють стан, вони просто якось перетворюють вхідні дані). Хорошими прикладами цього є такі речі, як Path.Combine. Такі речі корисні і роблять для більш сильного синтаксису.
У проблемах , я з статикою численні:
По-перше, якщо у вас є статичні класи, залежності приховані. Розглянемо наступне:
public static class ResourceLoader
{
public static void Init(string _rootPath) { ... etc. }
public static void GetResource(string _resourceName) { ... etc. }
public static void Quit() { ... etc. }
}
public static class TextureManager
{
private static Dictionary<string, Texture> m_textures;
public static Init(IEnumerable<GraphicsFormat> _formats)
{
m_textures = new Dictionary<string, Texture>();
foreach(var graphicsFormat in _formats)
{
// do something to create loading classes for all
// supported formats or some other contrived example!
}
}
public static Texture GetTexture(string _path)
{
if(m_textures.ContainsKey(_path))
return m_textures[_path];
// How do we know that ResourceLoader is valid at this point?
var texture = ResourceLoader.LoadResource(_path);
m_textures.Add(_path, texture);
return texture;
}
public static Quit() { ... cleanup code }
}
Дивлячись на TextureManager, ви не можете сказати, які кроки ініціалізації необхідно виконати, переглянувши конструктор. Ви повинні заглибитися в клас, щоб знайти його залежності та ініціалізувати речі у правильному порядку. У цьому випадку йому потрібно ініціалізувати ResourceLoader перед запуском. Тепер розширте цей кошмар залежності, і ви, мабуть, здогадаєтесь, що буде. Уявіть, що ви намагаєтесь підтримувати код там, де немає чіткого порядку ініціалізації. Порівнюйте це із введенням залежності із екземплярами - у такому випадку код навіть не компілюється, якщо залежності не виконано!
Крім того, якщо ви використовуєте статику, яка змінює стан, це як картковий будиночок. Ніколи не знаєш, хто має до чого доступ, і дизайн, як правило, нагадує монстра спагетті.
Нарешті, і не менш важливо, використання статики пов'язує програму з конкретною реалізацією. Статичний код є антитезою проектування для перевірки. Тестування коду, пронизаного статикою, є кошмаром. Статичний виклик ніколи не можна замінити на тестовий подвійний (якщо ви не використовуєте тестові фреймворки, спеціально розроблені для висміювання статичних типів), тому статична система робить все, що використовує його, миттєвим тестом інтеграції.
Коротше кажучи, статика підходить для деяких речей, а для дрібних інструментів чи коду, що викидається, я б не відмовляв їх використовувати. Однак, крім цього, вони є кривавим кошмаром для ремонтопридатності, гарного дизайну та простоти тестування.
Ось гарна стаття про проблеми: http://gamearchitect.net/2008/09/13/an-anatomy-of-despair-managers-and-contexts/