Подтвердить что ты не робот

Должен ли класс утилиты быть статичным?

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

  • Должны ли они быть статическими классами (поскольку у меня не будет никаких состояний для хранения)
  • Должны ли они быть нестатическими классами (так что если объекты не используются, они будут gc'd)

PS: По статическому классу я имел в виду класс со статическими методами (а не внутренний статический класс)

Пожалуйста, дайте советы по выбору дизайна для этого?

4b9b3361

Ответ 1

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

Ответ 2

Мои классы утилиты выглядят следующим образом:

// final, because it not supposed to be subclassed
public final class FooUtil {

    // private constructor to avoid unnecessary instantiation of the class
    private FooUtil() {
    }

    public static int doSomethingUseful() {
    }

    // ...
}

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

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

Ответ 3

Просто потому, что что-то может быть статическим, не означает, что он должен быть статическим.

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

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

Ответ 4

Самый простой способ определить класс Utility - это перечисление без экземпляров

public enum Utility {;
     public static int utilityMethod(int x) { /* ... */ }
}

Класс утилиты не должен иметь никакого состояния или иметь минимальное состояние, поэтому вы не должны беспокоиться о GC.

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

Ответ 5

Хорошо сделать класс нестационарным с помощью частного конструктора:

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

Если вы можете сделать их статичными, то обязательно сделайте это!

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

Ответ 9

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

Ответ 10

Никто здесь не упоминает, что статические методы утилиты не расширяемы. Вы не можете их переопределить. Вы не можете воспользоваться ООП (в частности, полиморфизм, который является самой мощной функцией ООП). Это приводит к дублированию кода.

P.S. Я нашел эту статью очень полезной. http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html