Должны ли частные вспомогательные методы быть статическими, если они могут быть статическими - PullRequest
192 голосов
/ 12 февраля 2009

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

public class Example {
   private Something member;

   public double compute() {
       double total = 0;
       total += computeOne(member);
       total += computeMore(member);
       return total;         
   }

   private double computeOne(Something arg) { ... }
   private double computeMore(Something arg) {... } 
} 

Есть ли какая-либо конкретная причина для указания computeOne и computeMore в качестве статических методов - или по какой-то конкретной причине нет?

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

Ответы [ 21 ]

3 голосов
/ 07 ноября 2012

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

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

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

3 голосов
/ 12 февраля 2009

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

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

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

3 голосов
/ 12 февраля 2009

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

В приведенном вами примере вы утверждаете, что computeOne и computeMore не должны иметь доступа к внутренним элементам класса, так что дайте возможность сопровождающим класса вмешиваться во внутренние элементы.

2 голосов
/ 12 февраля 2009

Статический / нестатический вопрос сводится к "нужно ли мне использовать объект этого класса"?

Итак, вы передаете объект между разными методами? Содержит ли объект информацию, которая полезна вне контекста статических методов? Есть ли причина не определять методы в обоих направлениях, если вы будете использовать их в обоих направлениях?

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

2 голосов
/ 12 февраля 2009

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

1 голос
/ 25 октября 2012
  1. Без статического модификатора вы не сможете понять, что метод не имеет состояния без дополнительного анализа, который можно легко сделать, когда вы (пере) напишите метод.

  2. Тогда модификатор «static» может дать вам идеи о рефакторинге помимо других вещей, которые другие могут счесть бесполезными. Например. перемещение метода в некоторый класс Utility или преобразование его в метод-член ..

1 голос
/ 05 августа 2011
class Whatever {

    public static varType myVar = initializeClassVariable();

    private static varType initializeClassVariable() {

        //initialization code goes here
    }
}

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

1 голос
/ 25 ноября 2009

Оффтопик: я бы оставил вспомогательные методы в автономном классе утилит / помощников, содержащем только статические методы.

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

1 голос
/ 23 февраля 2009

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

0 голосов
/ 25 ноября 2009

Как говорили многие, сделайте это как статический ! Вот правило большого пальца, которому я следую: если вы думаете, что метод - это просто математическая функция , то есть он не имеет состояния, не включает никаких переменных экземпляра (=> нет синего цвета [in eclipse] в методе ), и результат метода будет таким же для числа вызовов 'n' (с теми же параметрами, конечно), затем отметьте этот метод как STATIC.

И если вы считаете, что этот метод будет полезен для другого класса, в противном случае переместите его в класс Util, в противном случае поместите метод как private в тот же класс. (минимизация доступности)

...