Я любил вспомогательные классы, заполненные статическими методами. Они сделали большую консолидацию вспомогательных методов, которые в противном случае могли бы привести к избыточности и адскому обслуживанию. Они очень просты в использовании, без инстанцирования, без утилизации, просто fire'n'forget. Я думаю, это была моя первая невольная попытка создать сервис-ориентированную архитектуру - множество сервисов без сохранения состояния, которые просто сделали свою работу и ничего больше. Однако по мере роста системы появляются драконы.
Полиморфизм
Допустим, у нас есть метод UtilityClass.SomeMethod, который радостно гудит. Внезапно нам нужно немного изменить функциональность. Большая часть функциональности одинакова, но, тем не менее, мы должны изменить несколько частей. Если бы это не был статический метод, мы могли бы создать производный класс и изменить содержимое метода по мере необходимости. Поскольку это статический метод, мы не можем. Конечно, если нам просто нужно добавить функциональность либо до, либо после старого метода, мы можем создать новый класс и вызвать внутри него старый класс - но это просто грубо.
Проблемы интерфейса
Статические методы не могут быть определены через интерфейсы по логическим причинам. И поскольку мы не можем переопределить статические методы, статические классы бесполезны, когда нам нужно передать их через их интерфейс. Это лишает нас возможности использовать статические классы как часть шаблона стратегии. Мы могли бы исправить некоторые проблемы, передавая делегаты вместо интерфейсов .
Тестирование
Это в основном идет рука об руку с интерфейсом, упомянутым выше. Поскольку наша способность обмениваться реализациями очень ограничена, у нас также будут проблемы с заменой производственного кода тестовым кодом. Опять же, мы можем обернуть их, но это потребует, чтобы мы изменили большие части нашего кода, чтобы иметь возможность принимать обертки вместо реальных объектов.
Fosters blob
Поскольку статические методы обычно используются в качестве служебных методов, а служебные методы обычно имеют разные цели, мы быстро получим большой класс, заполненный непоследовательной функциональностью - в идеале каждый класс должен иметь одну цель в системе , Я бы предпочел проводить занятия в пять раз, если их цели четко определены.
Параметр ползучести
Начнем с того, что этот маленький симпатичный и невинный статический метод может принимать один параметр. По мере роста функциональности добавляется пара новых параметров. Вскоре добавляются дополнительные параметры, которые являются необязательными, поэтому мы создаем перегрузки метода (или просто добавляем значения по умолчанию на языках, которые их поддерживают). Вскоре у нас есть метод, который принимает 10 параметров. Только первые три действительно необходимы, параметры 4-7 являются необязательными. Но если указан параметр 6, 7-9 также должны быть заполнены ... Если бы мы создали класс с единственной целью сделать то, что сделал этот статический метод, мы могли бы решить это, приняв необходимые параметры в конструктор и позволяющий пользователю устанавливать необязательные значения через свойства или методы для одновременного задания нескольких взаимозависимых значений. Кроме того, если метод вырос до такой степени сложности,
Требовательные потребители для создания экземпляра классов без причины
Один из наиболее распространенных аргументов: зачем потребовать, чтобы потребители нашего класса создавали экземпляр для вызова этого единственного метода, но впоследствии не использовали этот экземпляр? Создание экземпляра класса является очень дешевой операцией в большинстве языков, поэтому скорость не является проблемой. Добавление дополнительной строки кода для потребителя - это низкая стоимость, чтобы заложить основу гораздо более удобного решения в будущем. И, наконец, если вы хотите избежать создания экземпляров, просто создайте одноэлементную оболочку вашего класса, которая позволяет легко использовать повторно - хотя это делает требование, чтобы ваш класс не имел состояния. Если это не состояние, вы все равно можете создавать статические методы-обертки, которые обрабатывают все, но при этом дают вам все преимущества в долгосрочной перспективе. В заключение,
Только ситхи имеют дело с абсолютами.
Конечно, есть исключения из моей неприязни к статическим методам. Истинные служебные классы, которые не представляют опасности для вздутия, являются отличными примерами для статических методов - System.Convert в качестве примера. Если ваш проект одноразовый без каких-либо требований для будущего обслуживания, общая архитектура на самом деле не очень важна - статическая или нестатическая, на самом деле не имеет значения - однако скорость разработки имеет значение.
Стандарты, стандарты, стандарты!
Использование методов экземпляра не мешает вам также использовать статические методы, и наоборот. Пока есть основания для дифференциации и она стандартизирована. Нет ничего хуже, чем просматривать бизнес-уровень с различными методами реализации.
this
, вы должны управлять глобальным состоянием и т.д. если вам нравится процедурное программирование, сделайте это. Но учтите, что тогда вы потеряете многие структурные преимущества ОО.Я предпочитаю статичный способ. Поскольку класс не представляет объект, не имеет смысла создавать его экземпляр.
Классы, которые существуют только для их методов, должны оставаться статическими.
источник
Если нет причин создавать экземпляр класса для выполнения функции, используйте статическую реализацию. Зачем заставлять потребителей этого класса создавать экземпляр, когда он не нужен.
источник
Если вам не нужно сохранять состояние объекта, то нет необходимости создавать его экземпляр в первую очередь. Я бы пошел с единственным статическим методом, которому вы передаете параметры.
Я бы также предупредил против гигантского класса Utils, который имеет десятки несвязанных статических методов. Это может стать неорганизованным и громоздким в спешке. Лучше иметь много классов, каждый из которых имеет несколько связанных методов.
источник
Я бы сказал, что лучше использовать статический метод. И я бы также сделал класс статичным, чтобы вам не пришлось беспокоиться о случайном создании экземпляра класса.
источник
Я действительно не знаю, какова ситуация здесь, но я бы посмотрел на то, чтобы поместить его как метод в один из классов, к которым принадлежат arg1, arg2 или arg3 - Если вы можете семантически сказать, что один из этих классов будет владеть метод.
источник
Я бы предположил, что сложно ответить на основании предоставленной информации.
Моя интуиция заключается в том, что если у вас будет только один метод и вы собираетесь немедленно выбросить класс, то сделайте его статическим классом, который принимает все параметры.
Конечно, трудно сказать точно, почему вам нужно создать отдельный класс только для этого одного метода. Является ли это типичной ситуацией в «классе коммунальных услуг», как большинство полагает? Или вы реализуете некоторый класс правил, которых может быть больше в будущем.
Например, этот класс должен быть подключаемым. Затем вы захотите создать интерфейс для вашего единственного метода, а затем вы захотите, чтобы все параметры передавались в интерфейс, а не в конструктор, но вы не хотели бы, чтобы он был статическим.
источник
Может ли ваш класс стать статичным?
Если так, то я бы сделал это классом Utilities, в который я поместил бы все свои однофункциональные классы.
источник
Если этот метод не имеет состояния и вам не нужно передавать его, тогда имеет смысл определить его как статический. Если вам НЕОБХОДИМО передать метод, вы можете рассмотреть возможность использования делегата, а не другого предложенного вами подхода.
источник
Для простых приложений и
internal
помощников я бы использовал статический метод. Для приложений с компонентами мне нравится среда Managed Extensibility Framework . Вот выдержка из документа, который я пишу, чтобы описать шаблоны, которые вы найдете в моих API.I[ServiceName]Service
интерфейсом.В качестве надуманного примера:
источник
Я бы просто сделал все в конструкторе. вот так:
или
источник
Еще один важный вопрос, который следует рассмотреть, - будет ли система работать в многопоточной среде и будет ли поточно-ориентированный метод иметь статический метод или переменные ...
Следует обратить внимание на состояние системы.
источник
Вы могли бы избежать ситуации все вместе. Попробуйте рефакторинг, чтобы вы получили
arg1.myMethod1(arg2, arg3)
. Поменяйте местами arg1 с arg2 или arg3, если это имеет больше смысла.Если у вас нет контроля над классом arg1, то украсьте его:
Причина заключается в том, что в ООП данные и методы, обрабатывающие эти данные, принадлежат друг другу. Плюс вы получаете все преимущества, о которых говорил Марк.
источник
Я думаю, что если свойства вашего класса или экземпляра класса не будут использоваться в конструкторах или в ваших методах, методы не должны разрабатываться как «статический» шаблон. Статический метод всегда должен рассматриваться как «помощь».
источник
В зависимости от того, хотите ли вы только что-то сделать или сделать и вернуть что-то, вы можете сделать это:
источник