Где вы сохраняете Константы, используемые во всей вашей заявке?

Является ли интерфейс приемлемым местом для хранения моих

public static final Foo bar

Вы экстраполируете их для чтения из-за пределов программы? Вы составляете для него суперкласс?

Как вы это делаете, когда возникает ситуация?

Ответ 1

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

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

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

Ответ 2

Если вы говорите о простом приложении, подход класса Constants подходит:

public class Constants {
    private Constants() {} // no way to instantiate this class
    public static final String MY_VAL = "123";
}

Если вы создаете более крупное приложение, вы должны использовать инъекцию зависимостей, посмотрите Как я могу вставить значение свойства в Spring Bean, который был настроен используя аннотации?

Ответ 3

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

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

public final class Const {
    private Const() {} // prevent instantiation

    /** Group1 constants pertain to blah blah blah... */
    public static final class Group1 {
        private Group1() {} // prevent instantiation

        public static final int MY_VAL_1 = 1;
        public static final int MY_VAL_2 = 42;
    }

    /** Group2 constants pertain to blah blah blah... */
    public static final class Group2 {
        private Group2() {} // prevent instantiation

        public static final String MY_ALPHA_VAL = "A";
        public static final String MY_ALPHA_VAL = "B";
    }

}

Ответ 4

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

Ответ 5

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