Подтвердить что ты не робот

В каких ситуациях статический метод является хорошей практикой?

Я прочитал следующие обсуждения:

Если частные вспомогательные методы являются статическими, если они могут быть статическими, и
Должны ли все методы быть статическими, если их класс не имеет переменных-членов

Похоже, что люди вообще принимали статические методы, но немного скептически относятся к ним по следующим двум причинам:

  • Их трудно проверить.
  • Они нарушают принцип OO. (Oни являются функциями, а не методами, человек.)

И наиболее приемлемыми статическими методами являются частные статические. Но почему же существуют статические методы вообще, и в каких ситуациях они первоочередны?

4b9b3361

Ответ 1

Статические методы сами по себе не трудно тестировать. Проблема в том, что другой код, вызывающий статический метод, трудно проверить, потому что вы не можете заменить статические методы.

Я думаю, что статические методы прекрасны, когда они являются частными или когда они являются "полезными" методами - например. чтобы выполнить экранирование строки. Проблема возникает, когда вы используете статические методы для вещей, которые вы хотите отмахиваться или иным образом заменять в тестах. Методы Factory также могут быть полезны, хотя инъекция зависимостей, как правило, является лучшим подходом - опять же, отчасти это зависит от того, хотите ли вы иметь возможность заменить функциональность тестов.

Что касается не "OO" - не все, что вы пишете в общем языке OO, должно быть "чистым" OO. Иногда маршрут, отличный от OO, просто более прагматичен и приводит к более простому коду. У Эрика Липперта есть замечательная запись в блоге об этом, чего я, к сожалению, сейчас не могу найти. Тем не менее, есть комментарий в этот пост, который имеет значение. Он говорит о методах расширения, а не о статических методах, но принцип тот же.

Часто используемые методы расширения часто подвергаются критике как "недостаточно ООП". Это кажется мне поставить перед собой тележку лошади. Цель ООП заключается в предоставить рекомендации по структурированию крупных программных проектов, написанных группы людей, которым не нужно знать внутренние детали каждого другая работа, чтобы быть продуктивный. Цель С# - быть полезный язык программирования, который позволяет нашим клиентам быть продуктивными на наших платформах. Ясно, что ООП полезны и популярны, и мы поэтому попытался упростить программы в стиле ООП на С#. Но Цель С# не "быть ООП язык". Мы оцениваем функции на основе о том, полезны ли они для нашего клиентов, а не на основе того, являются ли они строго соответствуют некоторым абстрактным академический идеал того, что делает язык объектно-ориентированный. Что ж счастливо берут идеи от оо, функциональный, процедурный, императивный, декларативный, что бы то ни было, если мы может сделать последовательный, полезный продукт что приносит пользу нашим клиентам.

Ответ 2

Я бы сказал, что статические методы определенно хорошо, когда они функции, т.е. они не выполняют IO, не имеют никакого внутреннего состояния и используют только их параметры для вычисления их возвращения стоимость.

Я бы также распространил это на методы, которые изменяют состояние их параметров, но если это делается чрезмерно, статический метод должен быть надлежащим образом методом экземпляра класса параметров, в котором он в основном работает.

Ответ 3

Подумайте об этом на мгновение. В OO-кодировании каждый вызов функции выглядит следующим образом:

method(object this, object arg1, object arg2), где это объект, который вы вызываете. Для этого все это действительно синтаксический сахар. Кроме того, он позволяет четко определять область переменных, потому что у вас есть переменные объекта и т.д.

Статические методы просто не имеют параметра "this". Т.е. вы передаете переменные и, возможно, получите результат. 1.) является основной причиной, по которой люди избегают их, вы не можете создать интерфейс для статического метода (пока), поэтому вы не можете издеваться над статическим методом для его проверки.

Во-вторых, OO - это процедуры и т.д. Статические методы имеют большой смысл в определенных ситуациях, но они всегда могут быть превращены в метод объекта.

Помните, вы не могли удалить это без взлома:

static void Main(string[] args)
{
}

Код, запускающий ваше приложение, ДОЛЖЕН быть разрешен без ссылки на объект. Таким образом, они дают вам гибкость, независимо от того, будете ли вы использовать их в своем сценарии, и будут основываться на ваших требованиях.

Ответ 4

Статические методы хороши в большинстве ситуаций, когда одноэлементный шаблон дает слишком большую гибкость.

Например, возьмите простую утилиту, например, поднимите примитиву до власти - очевидно, вам никогда не понадобится полиморфизм. Примитивные значения имеют статический тип, а математические операции четко определены и не изменяются. Это не похоже на то, что вы когда-нибудь столкнетесь с ситуацией с двумя разными внедрения не могут переключаться между ними, не переписывая весь ваш клиентский код.


(ирония выключена)

Современные JVM очень хороши при построении небольших вызовов, если загружена только одна реализация интерфейса. Если вы не профилировали свой код и не знаете, как отправлять ваши утилиты на интерфейс, это накладные расходы, у вас нет оправдания за то, что ваши утилиты в интерфейсе, которые могут быть изменены при необходимости.

Ответ 5

Другим хорошим сценарием для статических методов являются реализации шаблона Factory, где вы разрешаете экземпляры класса, который будет создан в частности.

Рассмотрим класс Calendar, который имеет набор статических методов getInstance, каждый возвращающий экземпляры, заправленные нужной TimeZone и/или Locale или по умолчанию.

Ответ 6

Я думаю, что определенный случай для статических методов , если вы не можете сделать их динамическими, потому что вы не можете изменить класс.

Это типичный для объектов JDK, а также все объекты, поступающие из внешних библиотек, а также примитивные типы.

Ответ 7

Я часто использую статические методы factory вместо или совместно с публичными конструкторами.

Я делаю это, когда мне нужен конструктор, который делает то, чего вы не ожидаете от конструктора. То есть загрузить параметры из файла или базы данных.

Этот подход также дает возможность называть "конструкторы", основываясь на том, что они делают. Это особенно полезно, когда самих параметров недостаточно, чтобы выяснить, что происходит в конструкторе.

Sun использует этот подход в

Class.forName("java.lang.Integer");

и

Boolean.valueOf("true");

Ответ 8

Прежде всего, вы не можете отбрасывать статические методы, по которым люди все еще используют его.

  • некоторые шаблоны проектирования основаны на статических методах, например, singleton:

    Config.GetInstance();

  • Вспомогательные функции, скажем, у вас есть байт-поток, и вы хотите, чтобы функция преобразует его в строку из шестнадцатеричных чисел.

существует много применений для статических методов, говорящих, что это не означает, что некоторые люди слишком сильно злоупотребляют им (обзор кода - лучший вариант, когда люди злоупотребляют кодом).

Ответ 9

Утилиты классов могут быть в порядке, чтобы быть статическими. Как и в предыдущем примере, с экранированием строк. Проблема заключается в том, что эти классы utils выполняют функции, которые мы хотели бы высмеять. Например, класс FileUtils в apache commons - часто бывает так, что я хочу издеваться над файловыми взаимодействиями без необходимости играть с реальными файлами. Если бы это был класс экземпляра, это было бы легко.

Ответ 10

Намного проще реорганизовать методы, статические. Это препятствует ненужным ссылкам на элементы, которые делают соединение плотным. Также проще понять код вызова, потому что он явно передает любые объекты, с которыми он взаимодействует.

Ответ 11

Вообще я избегаю статических методов, когда один экземпляр будет работать нормально. Этот единственный экземпляр может реализовать интерфейс и может легко издеваться. Я не говорю никогда, но редко использую статику. Я говорю своей команде, если они хотят использовать статичность, она должна быть очищена командой. Я почти никогда не отвечаю.