Я любил вспомогательные классы, заполненные статическими методами. Они сделали большую консолидацию вспомогательных методов, которые в противном случае могли бы привести к избыточности и адскому обслуживанию. Они очень просты в использовании, без инстанцирования, без утилизации, просто fire'n'forget. Я думаю, это была моя первая невольная попытка создать сервис-ориентированную архитектуру - множество сервисов без сохранения состояния, которые просто сделали свою работу и ничего больше. Однако по мере роста системы появляются драконы.
Полиморфизм
Допустим, у нас есть метод UtilityClass.SomeMethod, который радостно гудит. Внезапно нам нужно немного изменить функциональность. Большая часть функциональности одинакова, но, тем не менее, мы должны изменить несколько частей. Если бы это не был статический метод, мы могли бы создать производный класс и изменить содержимое метода по мере необходимости. Поскольку это статический метод, мы не можем. Конечно, если нам просто нужно добавить функциональность либо до, либо после старого метода, мы можем создать новый класс и вызвать внутри него старый класс - но это просто грубо.
Проблемы интерфейса
Статические методы не могут быть определены через интерфейсы по логическим причинам. И поскольку мы не можем переопределить статические методы, статические классы бесполезны, когда нам нужно передать их через их интерфейс. Это лишает нас возможности использовать статические классы как часть шаблона стратегии. Мы могли бы исправить некоторые проблемы, передавая делегаты вместо интерфейсов .
Тестирование
Это в основном идет рука об руку с интерфейсом, упомянутым выше. Поскольку наша способность обмениваться реализациями очень ограничена, у нас также будут проблемы с заменой производственного кода тестовым кодом. Опять же, мы можем обернуть их, но это потребует, чтобы мы изменили большие части нашего кода, чтобы иметь возможность принимать обертки вместо реальных объектов.
Fosters blob
Поскольку статические методы обычно используются в качестве служебных методов, а служебные методы обычно имеют разные цели, мы быстро получим большой класс, заполненный непоследовательной функциональностью - в идеале каждый класс должен иметь одну цель в системе , Я бы предпочел проводить занятия в пять раз, если их цели четко определены.
Параметр ползучести
Начнем с того, что этот маленький симпатичный и невинный статический метод может принимать один параметр. По мере роста функциональности добавляется пара новых параметров. Вскоре добавляются дополнительные параметры, которые являются необязательными, поэтому мы создаем перегрузки метода (или просто добавляем значения по умолчанию на языках, которые их поддерживают). Вскоре у нас есть метод, который принимает 10 параметров. Только первые три действительно необходимы, параметры 4-7 являются необязательными. Но если указан параметр 6, 7-9 также должны быть заполнены ... Если бы мы создали класс с единственной целью сделать то, что сделал этот статический метод, мы могли бы решить это, приняв необходимые параметры в конструктор и позволяющий пользователю устанавливать необязательные значения через свойства или методы для одновременного задания нескольких взаимозависимых значений. Кроме того, если метод вырос до такой степени сложности,
Требовательные потребители для создания экземпляра классов без причины
Один из наиболее распространенных аргументов: зачем потребовать, чтобы потребители нашего класса создавали экземпляр для вызова этого единственного метода, но впоследствии не использовали этот экземпляр? Создание экземпляра класса является очень дешевой операцией в большинстве языков, поэтому скорость не является проблемой. Добавление дополнительной строки кода для потребителя - это низкая стоимость, чтобы заложить основу гораздо более удобного решения в будущем. И, наконец, если вы хотите избежать создания экземпляров, просто создайте одноэлементную оболочку вашего класса, которая позволяет легко использовать повторно - хотя это делает требование, чтобы ваш класс не имел состояния. Если это не состояние, вы все равно можете создавать статические методы-обертки, которые обрабатывают все, но при этом дают вам все преимущества в долгосрочной перспективе. В заключение,
Только ситхи имеют дело с абсолютами.
Конечно, есть исключения из моей неприязни к статическим методам. Истинные служебные классы, которые не представляют опасности для вздутия, являются отличными примерами для статических методов - System.Convert в качестве примера. Если ваш проект одноразовый без каких-либо требований для будущего обслуживания, общая архитектура на самом деле не очень важна - статическая или нестатическая, на самом деле не имеет значения - однако скорость разработки имеет значение.
Стандарты, стандарты, стандарты!
Использование методов экземпляра не мешает вам также использовать статические методы, и наоборот. Пока есть основания для дифференциации и она стандартизирована. Нет ничего хуже, чем просматривать бизнес-уровень с различными методами реализации.