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

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

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

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

Ответы [ 20 ]

2 голосов
/ 18 марта 2009

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

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

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

2 голосов
/ 18 марта 2009

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

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

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

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

1 голос
/ 19 марта 2009

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

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.
1 голос
/ 19 марта 2009

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

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

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

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

1 голос
/ 19 марта 2009

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

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

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

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

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

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

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

1 голос
/ 18 марта 2009

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

1 голос
/ 18 марта 2009

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

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

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

0 голосов
/ 07 апреля 2009

Статика пахнет

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

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

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

0 голосов
/ 18 марта 2009

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

0 голосов
/ 18 марта 2009

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

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

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