Стоит ли избегать статических классов?
-
19-09-2019 - |
Вопрос
считаются ли статические классы плохой практикой?Пару дней назад я прочитал статью об этом (не могу ее найти, извините), в которой по сути говорилось, что наличие статических классов (особенно «вспомогательных» классов) обычно является признаком плохого кода.Правильно ли это, и если да, то по каким причинам?
Решение
Злоупотребление статическими классами можно считать плохой практикой.Но то же самое можно сказать и о злоупотреблении любой языковой особенностью.
Я не делаю различия между нестатическим классом, имеющим только статические методы, и статическим классом.По сути, это одно и то же, за исключением того, что статические классы позволяют компилятору реализовать намерения разработчика (без создания экземпляра этого класса, удобный синтаксис для доступа к его функциональности, и т. д.).
Как вы говорите, распространение классов «Помощник» может доставить вам проблемы (дизайн, ремонтопригодность, читабельность, обнаруживаемость, другие возможности...).Здесь нет аргументов.Но можете ли вы утверждать, что класс «Помощник» никогда соответствующий?Я сомневаюсь в этом.
Действительно, ответственное использование статических классов может принести большую пользу вашему коду:
- А
Enumerable
Статический класс предоставляет набор методов расширения, которые полюбились большинству из нас.Они представляют собой логический набор функций/бизнес-логики, не связанный с экземпляром какого-либо конкретного типа. - Услуги, предоставляемые средой/контекстом:например, ведение журнала, конфигурация (иногда)
- Другие (о которых я сейчас не могу вспомнить :))
Так что нет, в целом это неплохая практика.Просто используйте их с умом...
Другие советы
Означает ли это «Использование статических классов неправильно» (в этом случае статья неверна) или «Статические классы часто встречаются в плохо написанном коде» (в этом случае речь не идет о том, что статические классы сами по себе плохи, а о том, что они иногда используются неправильно)
Статические функции более эффективны, чем нестатические, поскольку вам не нужно создавать экземпляр объекта для их использования или передавать указатель this в вызовы методов.
Использование статических классов для хранения глобальных переменных — это другое дело: в этом случае основное правило заключается не в том, что «статика — это плохо», а в том, что «глобальные переменные — это плохо».
Я думаю, что общий аргумент против сохранения изменяемого состояния в статических классах и, по сути, использования их в качестве глобальных переменных.Нет ничего плохого в статических вспомогательных методах статического класса.
А что касается того, почему глобальные переменные плохи, я уверен, что здесь и в Google вы найдете полмиллиона страниц и сообщений в блогах об этом.
Неа, это не совсем правильно.
Существует множество функций, которые не относятся к экземпляру объекта и не требуют состояния.Например, рассмотрим «Математические» функции.
Почти во всех языках есть что-то вроде:
y = Math.round(x);
Таким образом, функция round является статической.Если бы вы были сумасшедшими, вы могли бы привести доводы в пользу чего-то вроде (C#):
class RoundFunction<T> : GeneralMathFunction<T>
{
public override T Operate (params object[] variables) {
..
}
}
Но, ИМХО, это было бы немного странно.
Конечно, бывают случаи, когда слишком много статических функций являются признаком того, что что-то пошло не так, но в разумных пределах это не «плохо».
Вот несколько ссылок на некоторые сообщения в блогах Google по тестированию о том, почему статические методы могут ухудшить тестируемость вашего кода, а также почему статические методы (которые являются плохой частью статических классов) создают всевозможные потенциально неожиданные связи и взаимодействия между компонентами.
Бывают ситуации, когда у вас есть класс Utility, в котором все методы являются статическими.В этом случае, если вы сделаете класс статическим, это ясно укажет на ваше намерение.И, по крайней мере, в C# внутри статического класса не может быть нестатических методов.
Я постоянно использую статические служебные классы в своем коде для методов, которые вызываются довольно часто, но создавать экземпляры было бы затруднительно.Примером может быть простой класс ведения журнала, например:
public static class Logging
{
public static UpdateAction(int id, object data)
{
SqlConnection connection = new SqlConnection("conn string from config file");
// more logic here...
}
}
Я никоим образом не заставляю эти классы и методы хранить какое-либо глобальное состояние, поскольку это может привести к огромным проблемам с параллелизмом и в целом является просто плохим дизайном.
Так что не избегайте статических классов, просто избегайте того, чтобы эти статические классы сохраняли какое-то глобальное состояние.