Я работаю над приложением со многими константами. При последнем обзоре кода выяснилось, что константы слишком разбросаны и должны быть все организованы в один «главный» файл констант. Разногласия о том, как их организовать. Большинство считает, что использование константного имени должно быть достаточно хорошим, но это приведет к коду, который выглядит следующим образом:
public static final String CREDITCARD_ACTION_SUBMITDATA = "6767";
public static final String CREDITCARD_UIFIELDID_CARDHOLDER_NAME = "3959854";
public static final String CREDITCARD_UIFIELDID_EXPIRY_MONTH = "3524";
public static final String CREDITCARD_UIFIELDID_ACCOUNT_ID = "3524";
...
public static final String BANKPAYMENT_UIFIELDID_ACCOUNT_ID = "9987";
Я считаю такой тип именования громоздким. Я подумал, что может быть проще использовать публичный вложенный класс и получить что-то вроде этого:
public class IntegrationSystemConstants
{
public class CreditCard
{
public static final String UI_EXPIRY_MONTH = "3524";
public static final String UI_ACCOUNT_ID = "3524";
...
}
public class BankAccount
{
public static final String UI_ACCOUNT_ID = "9987";
...
}
}
Эта идея не была хорошо принята, потому что она была «слишком сложной» (я не получил много подробностей о том, почему это может быть слишком сложно). Я думаю, что это создает лучшее разделение между группами связанных констант, а автозаполнение облегчает их поиск. Хотя я никогда не видел, чтобы это было сделано, поэтому мне интересно, является ли это общепринятой практикой или есть более веские причины, по которым этого не следует делать.
источник
Ответы:
Я не согласен ни с одним из двух предложений.
Константы должны быть в их соответствующих классах , а не в классе всех констант в любой из двух предложенных форм .
Не должно быть классов / интерфейсов только для констант.
Класс
CreditCard
(не внутренний класс) должен существовать. Этот класс / интерфейс имеет методы относительно кредитных карт, а также константUI_EXPIRY_MONTH
иUI_ACCOUNT_ID
.Должен существовать класс / интерфейс
BankAccount
(не внутренний класс). Этот класс / интерфейс имеет методы как для банковских счетов, так и для константUI_ACCOUNT_ID
.Например, в Java API каждый класс / интерфейс имеет свои константы. Они не входят в класс / интерфейс Constants с сотнями констант, либо сгруппированных во внутренние классы, либо нет.
Например, эти константы, относящиеся к наборам результатов, находятся в интерфейсе
ResultSet
:Этот интерфейс имеет сигнатуры методов относительно наборов результатов, и реализующие классы реализуют это поведение. Они не просто постоянные владельцы.
Эти константы, относящиеся к действиям пользовательского интерфейса, находятся в интерфейсе
javax.swing.Action
:Реализующие классы имеют поведение относительно действий пользовательского интерфейса, они не являются просто постоянными держателями.
Я знаю, по крайней мере, один интерфейс «константы» (
SwingConstants
) без методов, но у него нет сотен констант, только несколько, и все они связаны с направлениями и позициями элементов пользовательского интерфейса:Я думаю, что константы только классы не являются хорошим дизайном ОО.
источник
Это 100% неправильное решение проблемы констант, которые «трудно найти». Это фундаментальная ошибка (к сожалению, слишком часто совершаемая программистами) группировать вещи по техническим критериям, таким как постоянные, перечисления или интерфейсы.
За исключением архитектур слоев, вещи должны быть сгруппированы по их домену , а константы тем более, что они являются элементами очень низкого уровня. Константы должны быть частью классов или интерфейсов, которые используют их как часть своего API. Если вы не можете найти естественное место для их проживания, вам нужно очистить свой дизайн API.
Кроме того, один огромный файл констант убивает скорость разработки в Java, потому что константы встраиваются в классы, которые используют их во время компиляции, поэтому любое изменение вызывает перекомпиляцию всех этих файлов и всех, которые зависят от них. Если у вас есть один файл с константами, которые используются повсеместно, вы в значительной степени потеряете преимущество инкрементальной компиляции: наблюдайте, как Eclipse блокируется на 15 минут, поскольку он перекомпилирует весь ваш проект для каждого изменения в этом файле. И поскольку этот файл содержит все константы, используемые где-либо, вы будете изменять его довольно часто. Да, я говорю из личного опыта.
источник
Вы правы. Ваше предложение позволяет программисту
import static Constants.BankAccount.*
исключать и повторять бесчисленные повторения «BANKACCOUNT_». Конкатенация - плохая замена для фактического определения объема. Тем не менее, я не надеюсь, что вы измените культуру команды. У них есть представление о правильной практике, и вряд ли они изменятся, даже если вы покажете им 100 экспертов, которые говорят, что они не правы.Мне также интересно, почему у вас вообще есть один файл «Константы». Это очень плохая практика, если только эти константы не связаны каким-либо образом и не очень стабильны. Чаще всего это становится своего рода классом кухонной мойки, который постоянно меняется и зависит от всего.
источник
Оба подхода работают, и это важно в конце дня.
Тем не менее, ваш подход достаточно распространен, чтобы считаться шаблоном, или, точнее, достаточно хорошим улучшением по сравнению с постоянным интерфейсом антишаблонов. Я не понимаю, что в этом сложного, но вы должны обсудить это со своей командой.
источник
Одна из проблем с длинным списком констант заключается в поиске «правильной» константы для использования. Неизменно, кто-то добавляет константу в конце строки вместо того, чтобы добавить ее в группу, которой он принадлежал.
Что поднимает еще один вопрос для обсуждения с вашей командой - уже существует фактическая категоризация констант по их именам. Так что для них действительно не должно быть большого перехода от текущего состояния к тому, что вы предлагаете. Использование автозаполнения делает постоянный поиск еще проще.
Во всяком случае, ваше предложение помогает не использовать «неправильную» константу, даже если она может соответствовать конкретной ситуации. Оборачивая константы в репрезентативный класс, он побудит разработчиков задуматься, стоит ли им их использовать. Например, если я потяну
CreditCard.SomeConstant
для общего использования, я действительно должен задаться вопросом, почемуGeneral.SomeConstant
вместо этого нет для этой ситуации.Я был в проектах с огромным количеством констант, и я бы предпочел, чтобы метод, который вы предлагаете. Это чище, прямее и помогает избежать непреднамеренного использования.
источник
Я делаю это время от времени (в C #), особенно если мне нужно запрограммировать / проанализировать хорошо известную и фиксированную структуру XML или что-то похожее вложенное и тяжелое для строк ... например, пользовательский анализатор блоков конфигурации.
Я создаю вложенную структуру классов, соответствующую иерархической структуре XML, с именами классов, соответствующими элементам, содержащим свойство const string «ElementName» и аналогичное свойство, соответствующее каждому атрибуту (если есть).
Это позволяет очень легко программировать против соответствующего XML.
источник