В каких ситуациях статический метод является хорошей практикой? - PullRequest
36 голосов
/ 07 октября 2009

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

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

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

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

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

Ответы [ 11 ]

60 голосов
/ 07 октября 2009

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

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

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

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

18 голосов
/ 07 октября 2009

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

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

6 голосов
/ 07 октября 2009

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

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

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

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

Имейте в виду, вы не можете удалить это без взлома:

static void Main(string[] args)
{
}

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

4 голосов
/ 07 октября 2009

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

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


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

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

2 голосов
/ 07 октября 2009

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

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

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

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

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

и

Boolean.valueOf("true");
2 голосов
/ 07 октября 2009

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

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

2 голосов
/ 07 октября 2009

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

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

1 голос
/ 30 ноября 2012

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

1 голос
/ 14 мая 2010

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

1 голос
/ 10 октября 2009

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

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

    Config.GetInstance ();

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...