Должны ли все методы быть статическими, если в их классе нет переменных-членов - 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 ]

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

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

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

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

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

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

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

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

7 голосов
/ 19 марта 2009

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3 голосов
/ 19 марта 2009

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

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

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

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

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

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

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

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

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

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