Статические классы хороши, если они используются в нужных местах.
А именно: Методы, которые являются «листовыми» методами (они не изменяют состояние, они просто каким-то образом преобразуют входные данные). Хорошими примерами этого являются такие вещи, как 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/