Должны ли статические методы Java по умолчанию?

Скажите, что вы пишете метод foo() в классе A. foo никогда не имеет доступа ни к одному из состояний A. Вы ничего не знаете о том, что делает foo, или о том, как он себя ведет. Он может сделать что угодно.

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

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

Ответ 1

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

Однако то, о чем вы говорите, немного другое. Вы конкретно говорите о вспомогательных методах.

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

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


1. Основное преимущество: код более выразителен.

Создание этих методов static имеет по крайней мере важное преимущество: вы делаете его полностью явным в коде, который метод не должен знать какое-либо состояние экземпляра.. p >

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

2. Еще одно преимущество: код может быть проще рассуждать.

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

3. Преимущества оптимизации

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

4. Различия на уровне байтокода

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

Чтобы облегчить понимание этого раздела, используйте пример:

public class App {
    public static void main(String[] args) {
        WithoutStaticMethods without = new WithoutStaticMethods();
        without.setValue(1);
        without.calculate();

        WithStaticMethods with = new WithStaticMethods();
        with.setValue(1);
        with.calculate();
    }
}

class WithoutStaticMethods {

    private int value;

    private int helper(int a, int b) {
        return a * b + 1;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int calculate() {
        return helper(value, 2 * value);
    }
}

class WithStaticMethods {

    private int value;

    private static int helper(int a, int b) {
        return a * b + 1;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int calculate() {
        return helper(value, 2 * value);
    }
}

Интересующие нас строки - это вызовы helper(...) для классов WithoutStaticMethods и WithStaticMethods.

Без статических методов

В первом случае без статических методов при вызове вспомогательного метода JVM необходимо нажать ссылку на экземпляр, чтобы передать его в invokespecial. Взгляните на код метода calculate():

 0 aload_0
 1 aload_0
 2 getfield #2 <app/WithoutStaticMethods.value>
 5 iconst_2
 6 aload_0
 7 getfield #2 <app/WithoutStaticMethods.value>
10 imul
11 invokespecial #3 <app/WithoutStaticMethods.helper>
14 ireturn

Команда в 0 (или 1), aload_0, загрузит ссылку на экземпляр в стеке, и она будет потребляться позже invokespecial. Эта инструкция поместит это значение в качестве первого параметра функции helper(...) и никогда не будет использоваться, как мы можем видеть здесь:

0 iload_1
1 iload_2
2 imul
3 iconst_1
4 iadd
5 ireturn

Смотрите там нет iload_0? Он загружен без необходимости.

С помощью статических методов

Теперь, если вы объявите метод helper, static, то метод calculate() будет выглядеть так:

 0 aload_0
 1 getfield #2 <app/WithStaticMethods.value>
 4 iconst_2
 5 aload_0
 6 getfield #2 <app/WithStaticMethods.value>
 9 imul
10 invokestatic #3 <app/WithStaticMethods.helper>
13 ireturn

Различия заключаются в следующем:

  • там одна инструкция aload_0
  • вспомогательный метод теперь вызывается с помощью invokestatic

Ну, код вспомогательной функции также немного отличается: там нет this в качестве первого параметра, поэтому параметры фактически находятся в позициях 0 и 1, как мы видим здесь:

0 iload_0
1 iload_1
2 imul
3 iconst_1
4 iadd
5 ireturn

Заключение

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

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

Ответ 2

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

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

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

public class MathUtils
{
  public static float squareRoot(float x)
  {
    ... calculate square root of parameter x ...
    return root;
  }
}

Конечно, вы могли бы сделать версию "больше OOPy", которая выглядела бы так:

public class MathUtils
{
  private float x;
  public MathUtils(float x)
  {
    this.x=x;
  }
  public float squareRoot()
  {
    ... calculate square root of this.x ...
    return root;
  }
}

Но, если не удастся встретить какую-то абстрактную цель использования ООП, как это будет лучше? Он требует больше строк кода и менее гибкий.

(И да, теперь я использую функцию квадратного корня в стандартном классе Math. Я просто использовал это как удобный пример.)

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

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

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

Вы спрашиваете: "Должно ли всегда всегда быть статичным, независимо от каких-либо других соображений?" Я бы сказал: "Почти, но не совсем".

Единственная причина, по которой я могу думать, что это не статический, - это если подкласс хочет переопределить его.

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

Ответ 3

Нет. Никогда. Исключение составляют статические методы. OO - это все об объектах с поведением, которые вращаются вокруг состояния объекта. Imho, в идеале, не должно быть (или очень немногих) статических методов, потому что все, не связанное с состоянием объекта, могло (и избегать того, чтобы приводить понятие объекта ad absurdum, должно) быть размещено в простой старой функции в модуле уровень. Возможное исключение для фабрик, потому что Complex.fromCartesian(для примера wikipedia) читается так хорошо.

Конечно, это (редактирование: функции на уровне модуля) невозможно в однопарадигменном OO-языке (редактирование: как Java) - вот почему я такой преданный сторонник дизайна многопарадигменного языка, путь. Но даже на языке исключительно OO большинство методов будут вращаться вокруг состояния объекта и, следовательно, быть нестатическими. То есть, если ваш дизайн не имеет ничего общего с OO, но в этом случае вы используете неправильный язык.

Ответ 4

Интересный вопрос. С практической точки зрения, я не вижу смысла ставить методы private helper класса A (если они, конечно, не связаны с общедоступным статическим методом в A). Вы ничего не набираете - по определению, любой метод, который может понадобиться им, уже имеет экземпляр A в его распоряжении. И поскольку они являются закулисными методами, вам нечего сказать (или другому сотруднику), в конечном итоге, не решить, что один из этих помощников без гражданства может извлечь выгоду из знания состояния, что может привести к неприятности, связанные с рефакторингом.

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

Ответ 5

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

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

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

Ответ 6

Я обычно

При необходимости выполните следующие шаги:

a) Я пишу некоторый код в методе-члене, выясняю, что я могу, вероятно, повторно использовать часть этого кода и

Извлечение на нестатический метод

b) Теперь я увижу, нужен ли этому методу доступ к состоянию или если я могу удовлетворить его потребности одним или двумя параметрами и оператором return. Если последнее имеет место:

Сделать метод (закрытый) статическим

c) Если я найду, что я могу использовать этот код в других классах одного и того же пакета, я

Сделать метод общедоступным и переместить метод в класс вспомогательного пакета с видимостью по умолчанию

например. В пакете com.mycompany.foo.bar.phleeem я бы создал класс PhleeemHelper или PhleeemUtils с видимостью по умолчанию.

d) Если я тогда пойму, что мне нужна эта функциональность по всему моему приложению, я

Переместить класс-помощник в выделенный пакет

например. com.mycompany.foo.utils.PhleeemUtils

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

Ответ 7

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

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

Ответ 8

Java объединяет понятия модуля, пространства имен, adt и класса, как таковые, чтобы утверждать, что некоторая чистота OO-чистоты, ориентированная на класс, должна помешать вам использовать класс java в качестве модуля, пространства имен или adt, это смешно.

Да, методы должны быть статическими. Чисто внутренние методы поддержки должны быть частными; защитные методы; и функции полезности должны быть общедоступными. Кроме того, существует мир различий между статическим полем, статической константой и общедоступным статическим методом. Первое - это просто другое слово для "глобальной переменной"; и его почти всегда следует избегать, даже посредничество при помощи аксессуаров едва ограничивает ущерб. Второй относится к классу java как к пространству имен для символической константы, вполне приемлемым. Третий относится к классу java как к модулю для функции, так как следует избегать побочных эффектов общего характера или, при необходимости, ограничиваться любыми параметрами, передаваемыми функции. Использование static поможет вам избежать непреднамеренного нарушения этого доступа, обратившись к членам объекта.

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

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

Ответ 9

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

В любом случае, все классы java.util.Arrays являются статическими. Числовые классы Integer, Boolean, String имеют статические методы. Много статических методов. Все статические методы в этих классах либо преобразуются в соответствующие экземпляры классов, либо из них.

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

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

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

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

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

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

По той же причине OS/2 не смогла конкурировать с Microsoft, поскольку концепция ортогональности IBM была чисто машинной и основанной на данных, и IBM так гордо заявляла о своей истинной объектно-ориентированности и ложной объектно-ориентированной технологии Microsoft, которая потворствует человечеству. Они забыли, что у нас есть свои собственные различные ортогональные перспективы информации, которые не соответствуют данным и ортогональности на машинах или даже друг к другу.

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

Должен быть компромисс между эффективностью и эффективностью. Нет смысла иметь эффективные данные или объектную модель, которые вряд ли могут эффективно использоваться другими программистами.

Ответ 10

Если он ничего не делает с объектами этого класса, но фактически относится к этому классу (я бы рассмотрел его перемещение в другом месте), да, он должен быть статическим.

Ответ 11

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

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

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

Ответ 12

Это зависит от того, java.lang.Math не имеет метода, который не является статичным. (Вы можете сделать статический импорт для записи cos() вместо Math.cos()) Это не должно быть чрезмерным, но в качестве некоторого кода, который намерен быть вызван как утилита, он был бы приемлемым. I.g Thread.currentThread()

Ответ 13

Статический метод используется для определения метода (или переменной в этом отношении), который не связан с объектами, созданными из этого класса, а сам класс. Например, вам нужна переменная для подсчета количества созданных объектов. Вы бы поставили что-то вроде: "private static int экземпляры = 0;" а затем поместите что-то в конструктор для этого класса, который увеличивает "экземпляры", чтобы вы могли подсчитать его.

Ответ 14

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

Джошуа Блох в "Элементе 1: рассмотрим статические Factory методы вместо конструкторов" в Эффективная Java делает очень убедительный случай, что статические методы могут быть очень полезными. Он дает пример java.util.Collections класса 32 static Factory в качестве примера.

В одном случае у меня есть иерархия классов POJO, экземпляры которых могут быть автоматически сериализованы в XML и JSON, а затем десериализованы обратно в объекты. У меня есть статические методы, которые используют дженерики Java для десериализации: fromXML(String xml) и fromJSON(String json). Тип POJO, который они возвращают, неизвестен априори, но определяется текстом XML или JSON. (Я первоначально упаковал эти методы в класс-помощник, но было семантически чище перемещать эти статические методы в корневой класс POJO.)

Несколько других примеров:

  • Использование класса в качестве пространства имен для группировки связанных методов (например, java.lang.Math).
  • Метод действительно является вспомогательным методом для частного класса, без необходимости обращаться к переменным экземпляра (приведенный здесь случай). Просто не подглядывайте this -эквивалент в свой список аргументов!

Но не используйте статику бездумно или вы рискуете попасть в более неорганизованный и более процедурный стиль программирования.

Ответ 15

Нет, использование статики должно быть довольно нишевым.

В этом случае OP, скорее всего, "скрывает" состояние в параметрах, переданных в статический метод. Способ постановки вопроса делает это неочевидным (foo() не имеет входов или выходов), но я думаю, что в реальных примерах вещи, которые на самом деле должны быть частью состояния объекта, выпадают довольно быстро.

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

Ответ 16

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

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

В любом случае, по умолчанию для Java-методов не статично статично.

Говоря об этом последнем выпуске, они не должны быть статичными по умолчанию, потому что необходимость писать "статические" заставляет людей думать, прежде чем писать статические методы. Это хорошая практика, когда у вас гетерогенные команды (те, где Java больше всего подходит).

Ответ 17

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

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

Ответ 18

Я думаю, что позволить статическим методам в Java привести к довольно хаотичной реализации новичком, который не понимает OO правильно. Мы были там и думаем об этом. Если методы были статичными по умолчанию, насколько нам трудно понять принцип OO?

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

NB: Позвольте мне догадаться, вы случайно прочитали Clean Code?

Ответ 19

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

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

Ответ 20

Я думаю, что "private static" (edit: for methods) является своего рода оксюмороном в Java. Главным моментом статических методов, на мой взгляд, является предоставление доступа к функциям вне контекста экземпляров объектов. Другими словами, они практически всегда полезны, если они публичны. Если вы вызываете только метод из одного экземпляра объекта, и этот метод является закрытым, нет смысла делать его статическим. (редактирование: но это не имеет практического значения).

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

Ответ 21

Большинство статических методов написано потому, что

  • Вы разбиваете сложный метод на субметоды, или
  • Вы хотите, чтобы строка (или дата или...) имела некоторые функции, которые не имеют

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

Вторая причина дает всегда популярные классы StringUtil, DateUtil, FooUtil. Это проблематично, потому что у вас нет способа узнать, что они существуют, поэтому программисты часто пишут дубликаты этих методов. Решение, опять же, должно избегать использования String и Date все время. Начните создавать свои собственные объекты, возможно, обернув исходный объект. Статические методы становятся нестационарными методами нового объекта.

Ответ 22

Если foo() не имеет ничего общего с Object A, то почему этот метод существует?

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

Ответ 23

Множество интересных ответов.

Если вы отчаянно ищете правило, используйте это:

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

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

Конец истории.