Где вы храните константы, используемые в вашем приложении? - PullRequest
18 голосов
/ 03 июня 2011

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

public static final Foo bar

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

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

Ответы [ 5 ]

30 голосов
/ 03 июня 2011

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

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

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

5 голосов
/ 03 июня 2011

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

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

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

2 голосов
/ 16 августа 2013

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

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

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";
    }

}
1 голос
/ 03 июня 2011

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

0 голосов
/ 03 июня 2011

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

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