Это - плохая практика для класса, чтобы иметь только статические поля и методы?

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

Это - плохая практика для класса для содержания только статических членских переменных и статических методов?

70
задан Stephen Watkins 26 May 2012 в 03:29
поделиться

13 ответов

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

РЕДАКТИРОВАТЬ: В качестве запоздалой мысли, в целом, я думаю, что неплохо избегать использования языковых функций «просто потому» или потому, что вы думаете, что это «способ сделать это в Java». Я вспоминаю свою первую работу, когда у меня был класс, полный статических служебных методов, и один из старших программистов сказал мне, что я не полностью использовал возможности Java в объектно-ориентированном стиле, делая все свои методы «глобальными». Через 6 месяцев ее не было в команде.

88
ответ дан 24 November 2019 в 13:23
поделиться

Это совершенно разумно. Фактически, в C # вы можете определить класс с ключевым словом static специально для этой цели.

3
ответ дан 24 November 2019 в 13:23
поделиться

Звучит разумно.

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

13
ответ дан 24 November 2019 в 13:23
поделиться

Обратите внимание, что в Java специально введен статический импорт: ( http://en.wikipedia.org/wiki/Static_import )

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

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

Механизм может использоваться для ссылки отдельные члены класса:

 import static java.lang.Math.PI;
 import static java.lang.Math.pow;

или все статические члены класса:

 import static java.lang.Math.*;
2
ответ дан 24 November 2019 в 13:23
поделиться

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

Пока вы думаете об этом, я не вижу проблем с вашим решением.

.
2
ответ дан 24 November 2019 в 13:23
поделиться

Класс Collections в Java SDK имеет только статические члены.

Итак, вот так, пока у вас есть правильное обоснование - это неплохая конструкция

.
1
ответ дан 24 November 2019 в 13:23
поделиться

Как правило, именно так и создаются классы-утилиты, и в этом нет ничего плохого. Известными примерами являются o.a.c.l.StringUtils, o.a.c.d.DbUtils, o.s.w.b. ServletRequestUtils и т.д.

.
1
ответ дан 24 November 2019 в 13:23
поделиться

Полезные методы часто помещаются в классы, в которых используются только статические методы (например, StringUtils). Глобальные константы также помещаются в свой собственный класс, чтобы их можно было импортировать остальным кодом (public final static attributes)

Оба вида использования достаточно распространены и имеют частные конструкторы по умолчанию, чтобы не допустить их инстанцирования. Объявление класса final предотвращает ошибку в попытке переопределения статических методов.

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

1
ответ дан 24 November 2019 в 13:23
поделиться

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

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

Даже Java-дизайнеры создают утилитные классы (java.lang.Math приходит на ум)

Варианты:

double distance = Math.sqrt(x*x + y*y);  //using static utility class

vs:

RootCalculator mySquareRooter = new SquareRootCalculator();
mySquareRooter.setValueToRoot(x*x + y*y);
double distance;
try{
   distance = mySquareRooter.getRoot();
}
catch InvalidParameterException ......yadda yadda yadda.      

Даже если мы избежим многословного метода, мы все равно можем закончить на:

Mathemetician myMathD00d = new Mathemetician()
double distance = myMathD00d.sqrt(...);

в этом примере. sqrt() все еще статична, так какой же был бы смысл в создании объекта в первую очередь?

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

*.
1
ответ дан 24 November 2019 в 13:23
поделиться

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

Ярким примером является класс Math.

.
19
ответ дан 24 November 2019 в 13:23
поделиться

Просто не увлекайтесь. Обратите внимание, что класс java.lang.Math занимается только математическими функциями. Также у вас может быть класс StringUtilities, который содержит общие функции обработки строк, которых нет, например, в стандартном API. Но если ваш класс назван, например, Utilities, то это подсказка, что вы можете захотеть его разделить.

.
3
ответ дан 24 November 2019 в 13:23
поделиться

Статические методы меня не сильно беспокоят (за исключением тестирования).

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

.
9
ответ дан 24 November 2019 в 13:23
поделиться

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

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

.
0
ответ дан 24 November 2019 в 13:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: