Константы против свойств в Java

Какой должен быть лучший подход для объявления постоянного значения в моей Java-программе?

Это лучший способ объявить постоянное значение в файле.properties или объявить это значение как статический финал в природе в другом классе?

5 ответов

Решение

Ответ на вопрос зависит от того, чего вы хотите достичь. Но в этом есть и недоразумение.

Файлы свойств

Файлы свойств не предназначены для подстановки или альтернативы константам. Они используются для хранения настраиваемых значений, это могут быть ip, языки и т. Д. Загрузка констант из файла отрицательно сказывается на назначении констант.

Константы

Другой момент заключается в том, что публикуемые статические конечные переменные не являются хорошим подходом в java, предпочтительным способом является использование перечислителя (из Effective Java, пункт 30: используйте enum вместо int constatns). Перечисление заставит вас сгруппировать константы осмысленным образом, в то время как класс, полный случайных открытых констант, просто плохой дизайн. Enum позволяет вам предоставлять функциональные возможности, например, проверки, валидацию, связывать константу с несколькими объектами и ее можно использовать для переключателей. Другое дело, что перечисления скомпилированы, что делает их более эффективными и безопасными. Прочитайте книгу, объясняющую ее гораздо лучше, чем я когда-либо мог.

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

Файлы свойств и глобальный доступ к конфигурации

Представьте, что у вас есть ip в файле свойств, и вы хотите иметь доступ к этому значению из любого места в вашем коде. Вы можете просто прочитать значение и загрузить его в публичную статическую переменную final.

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

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

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

Заметка

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

Заметка 2

Многие люди говорят, что на самом деле не существует "лучшего способа" что-либо сделать. Я думаю, что это правда, но также верно и то, что если у вас есть доступ к книгам, таким как Effetive Java от Джошуа Блоха, вы должны читать их и учиться у людей, которые действительно долго программировали.

Объявите их как static final в вашем коде, если эти значения не являются средой, т.е. dev,qa,stage специфические и не меняются на протяжении всего жизненного цикла вашего кода.

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

Например:- у вас могут быть разные учетные данные для имени пользователя "admin" в вашей среде dev/qa/stage/prod.

Затем вы можете определить администратора как public static final String userId="admin" но пароль, который вы хотите предоставить из файла свойств, и измените его в соответствии со средой, в которой вы выполняете свой код.

лайк

dev.properties admin.password = 123456.

qa.properties admin.password = abcdef.

А затем прочитайте эти пароли из файла свойств в зависимости от вашей среды.

Реальный ответ зависит от ваших требований. В реальном мире нет "А лучше, чем В". Только: "A является более полезным, учитывая требования x,y,z, чем B".

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

Преимущества использования константы:

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

Недостатки констант:

  • Исправление требует, чтобы вы предоставили перекомпилированные файлы классов для ваших клиентов
  • для того, чтобы применить исправление, нужно либо остановить JVM, на котором выполняется ваш код; или, по крайней мере, ваш контейнер (например, WAR в Tomcat) необходимо повторно развернуть.

Свойства просто "наоборот".

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

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

Я попробовал оба способа - Файл и общедоступный статический финальный класс, и оба работают. Некоторые моменты, чтобы отметить, хотя:

  • Объявление в файле было бы особенно полезно, если бы ваша программа нуждалась в тестировании / запуске различными сторонами, которые хотели бы изменить эти константы. В этом случае они будут называться свойствами приложения / программы. Spring следует этому подходу для конфигурации.
  • Объявление их в классе потребовало бы повторного построения Приложения снова и снова, но если эти константы не изменяются или не требуются для доступа нескольких сторон, вы можете очень легко выбрать подход статического финального класса. В качестве примера Android объявляет константы, динамически генерируемые в файле R.java. Кстати, этот подход сохраняет контроль в вашей руке. Стороны, использующие ваш код, не смогут изменять эти константы. Файловый подход передает контроль в руки других для их изменения.

Object Mappers также предпочли бы, чтобы у вас были свойства Bean в конфигурационных файлах, но в Java-аннотации они находятся между ними и элегантно решают их.

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

Пример:

public static final String HOSTNAME = System.getProperty("my.host-name", "localhost");

Однако не всегда рекомендуется указывать значение по умолчанию.

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

Другие вопросы по тегам