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

Если все методы являются статическими, если их класс не имеет переменных-членов

У меня только что был аргумент с кем-то, с кем я работаю, и это действительно подслушивает меня. Если у вас есть класс, который имеет только такие методы, как calculateRisk или/и calculatePrice, класс неизменен и не имеет переменных-членов, если методы должны быть статичными, чтобы каждый раз не создавать экземпляр класса. Я использую следующий пример:

public class CalcService {
  public int calcPrice(Trade trade, Date date) {
    ...
  }
  public double calcRisk(Trade trace, Date date) {
    ...
  }
}

Должны ли эти методы быть static?

4b9b3361

Ответ 1

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

Ответ 2

Я бы сказал "да", но в этом случае можно было бы также аргументироваться за то, что просто поместили эти методы в объект Trade.

Ответ 3

В наши дни существует общее чувство против статических классов по причинам проверки.

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

Это может быть не полезно сейчас, но я вижу больше преимуществ в том, чтобы не использовать статический класс, чем использовать его.

Ответ 4

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

CalcService cs = new CalcService();
cs.calcPrice(trade, date);

а позже вы можете добавить новый механизм расчета:

CalcService cs = new CalcService(new WackyCalculationStrategy());
cs.calcPrice(trade, date);

Если вы сделаете этот класс интуитивным, тогда вы можете создавать разные экземпляры и передавать их, создавать экземпляры на лету и т.д. Вы можете дать им долгое поведение (например, сколько вычислений, связанных с торговлей X, этот объект был выполнен?) )

Ответ 5

Это сложный вызов. Помните, что Джош Блох говорит об API:

API, такие как алмазы, являются навсегда. У вас есть один шанс получить его так что дайте ему все возможное.

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

Ответ 6

Я бы сделал все статичным.

Ответ 7

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

Некоторые из ответов подразумевают, что метод не имеет состояния, но я действительно не хочу его видеть. Метод принимает состояние в виде параметров метода. Что делать, если эти параметры были указаны в объекте?

Ответ 8

Я бы сказал, что нет.

Намного сложнее изменить в будущем, если вы вызываете статические методы вместо экземпляров. С помощью методов экземпляра легко вводить ваши услуги, например. в Java с контейнером IoC/DI, например Guice или Spring.

Ответ 9

Ответ: да и нет. Все зависит от цели поведения метода. Например:

  • если эти методы являются просто утилитами, то имеет смысл сделать их статичными.

  • Если эти методы представляют собой своего рода бизнес-логику вашего приложения (скажем... веб-приложение), тогда вы можете сделать их максимально гибкими. В этом случае они станут простым классом POJO, как методы экземпляра. Это имеет не столь очевидную выгоду, что они могут быть преобразованы в Spring транзакционный beans или даже сеанс EJB3 beans с минимальными усилиями. Это также облегчает тестирование методов. Вы также можете создавать интерфейсы для этого bean и добавлять к нему дополнительные аспекты так, как вам нужно.

Ответ 10

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

Собственно, я бы наверняка удостоверился, что класс не будет создан, делая его абстрактным.

Ответ 11

Если вы сделаете его статическим, вы не сможете легко внедрить другую реализацию.

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

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

Я не знаю, может ли вычисление цен или рисков быть различным в вашем домене. Если существуют разные стратегии, переход к реализации стратегии без гражданства может иметь преимущества. Но это больше кода, и есть хороший шанс, что YAGNI.

Ответ 12

Я считаю, что методы без состояния обычно должны быть статическими.

  • В коде ясно, что нет объекта участвует
  • Он избегает бессмысленного конструктора Вызов

Я вижу нарушение этого правила для реализации стратегии-шаблона, как отметили многие люди.

Ответ 13

Это зависит от вашей цели:

Если ваша цель - написать как можно меньше строк кода, статический подход будет лучшим.

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

Ответ 14

Если методам нужна информация в торговом экземпляре для выполнения своей работы, то почему же эти методы не являются статическими членами класса Trade?

Ответ 15

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

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

Опять же, это может не произойти с вашим конкретным кодом, но я был однажды в этом приложении с такими классами (40-60 и более)

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

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

Строки кода этого приложения в 500k, а не все из них были в java, что затрудняет рефакторинг.

Если вы используете это в проекте линии 1k, то это не имеет значения.

Ответ 16

В приведенных выше ответах я читаю аргумент о том, что он не статичен для тестирования. Я не понимаю, почему, но я не familiair с процедурой тестирования вы используете.

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

Итак, я бы сказал: да сделайте их статичными.

(С замечанием о том, что я не знаю процедуры тестирования, где тестирование статических методов является проблемой)

Ответ 17

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

End result. Making it a not static gives you more functionality. Make class Singleton and you have everything a static does for you plus loosely coupling.

Ответ 18

По-моему, они должны быть статичными. Вы даже можете добиться повышения производительности, потому что компилятор /jit может встроить методы

Ответ 19

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

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

Ответ 20

Запах статики

В большинстве случаев статический метод является примером поведения, разведенного с данными. Он указывает, что что-то не инкапсулировано. например если вы видите методы проверки номера телефона, электронной почты и т.д. в классах util, спросите, почему они не являются этими полями, не имеют собственных классов. Даже классы библиотеки могут быть расширены для обеспечения пользовательского поведения. Наконец, в особых случаях, таких как java.lang.String(окончательный), вы можете использовать пользовательский myproject.String(с дополнительным поведением), который делегирует java.lang.String

Объекты - это способ доступа к поведению на языках OO. Не стоит беспокоиться о стоимости создания объекта и использовать статику вместо этого. Для большинства бизнес-программ этот подход представляет собой "беспроигрышный" подход к производительности.

Иногда вы используете функторы (методы, которые не используют состояние объекта) для выражения намерения. Не означает, что они должны быть статичными. Предупреждения IDE, которые предполагают, что метод может быть сделан статическим, не должны восприниматься серьезно.