Помещение статических членов в интерфейс (и реализация этого интерфейса) - плохая практика, и для него даже есть название - Constant Interface Antipattern , см. Эффективная Java , Правило 17:
Шаблон постоянного интерфейса - это плохое использование интерфейсов . То, что класс использует некоторые константы внутри, является деталью реализации. Реализация постоянного интерфейса приводит к просачиванию этой детали реализации в экспортируемый API класса. Для пользователей класса не имеет значения, что класс реализует постоянный интерфейс. На самом деле, это может даже сбить их с толку. Хуже того, это представляет собой обязательство: если в будущем выпуске класс будет изменен так, что ему больше не нужно будет использовать константы, он все равно должен реализовать интерфейс, чтобы гарантировать двоичную совместимость. Если нефинальный класс реализует постоянный интерфейс, пространство имен всех его подклассов будет загрязнено константами в интерфейсе.
В библиотеках платформы Java есть несколько постоянных интерфейсов, например java.io.ObjectStreamConstants
. Эти интерфейсы следует рассматривать как аномалии и не должны имитироваться.
Чтобы избежать некоторых ошибок постоянного интерфейса (потому что вы не можете помешать людям его реализовать), следует предпочесть правильный класс с частным конструктором (пример заимствован из Википедии ):
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
И для доступа к константам без необходимости их полной квалификации (т.е. без необходимости указывать перед ними имя класса) используйте статический импорт (начиная с Java 5):
import static Constants.PLANCK_CONSTANT;
import static Constants.PI;
public class Calculations {
public double getReducedPlanckConstant() {
return PLANCK_CONSTANT / (2 * PI);
}
}
Кто бы ни придумал эту гипотезу, каким бы гуру он или она ни был, он придумал ее на основе необходимости продолжать эффективно применять вредные привычки и практики. Гипотеза основана на пропаганде обоснованности плохих привычек в разработке программного обеспечения.
Я написал здесь ответ, опровергающий эту гипотезу: Как лучше всего реализовать константы в Java? объясняя безосновательность этой гипотезы.
В течение 10 лет этот вопрос оставался открытым, пока он не был закрыт в течение 2 часов после того, как я опубликовал свои доводы, опровергающие эту гипотезу, тем самым выставив НЕЖЕЛАНИЕ для обсуждения теми, кто придерживается этой ошибочной гипотезы.
Это те моменты, которые я высказал против гипотезы
Основанием для поддержки этой гипотезы является необходимость в методах и ОГРАНИЧИТЕЛЬНЫХ правилах, чтобы справиться с последствиями плохих программных привычек и методологий.
Сторонники тезиса « Постоянный шаблон интерфейса - это плохое использование интерфейсов» не могут назвать никаких причин, кроме тех, которые вызваны необходимостью справиться с последствиями этих вредных привычек и практик.
Решите основную проблему.
И тогда почему бы не в полной мере использовать и использовать каждую языковую функцию структуры языка Java для вашего собственного удобства. Куртки не требуются. Зачем изобретать правила, чтобы заблокировать свой неэффективный образ жизни, чтобы дискриминировать и инкриминировать более эффективный образ жизни?
Основная проблема
информационная организация. Информация, опосредующая процесс, и поведение этой информации должны быть сначала поняты вместе с так называемыми бизнес-правилами - до разработки или дополнения решений для процесса. Такой способ организации информации несколько десятилетий назад назывался нормализацией данных.
Тогда будет возможна только разработка решения, потому что согласование детализации и модульности компонентов решения с гранулярностью и модульностью компонентов информации является оптимальной стратегией.
Есть два или три существенных препятствия на пути к организации информации.
Отсутствие восприятия необходимости «нормализации» модели данных.
Заявления EF Codd о нормализации данных ошибочны, неполноценны и неоднозначны.
Последнее увлечение, маскирующееся под гибкую инженерию, - это ошибочное представление о том, что не следует планировать и обусловливать организацию модулей заранее, потому что вы можете рефакторинг по ходу дела. В качестве оправдания используется рефакторинг и постоянные изменения без препятствий со стороны будущих открытий. Существенные открытия в поведении информации о процессе заключаются в использовании бухгалтерских уловок для отсрочки получения прибыли и оценки, поэтому важные знания и их обработка сейчас считаются ненужными.
Использование констант интерфейса - хорошая практика.
Не придумывайте правила и не выдвигайте никаких фетв против этого только потому, что вам нравятся ваши специальные привычки в программировании.
Не запрещайте владение оружием по той причине, что есть люди, которые либо не умеют обращаться с оружием, либо склонны злоупотреблять оружием.
Если правила, которые вы придумываете, предназначены для новичков в программировании, которые не могут профессионально программировать и вы относитесь к их числу, тогда скажите об этом - не объявляйте свою фетву применимой к правильно нормализованным моделям данных.
Глупая аргументация - интерфейсы не предназначались камбалами языка Java для использования таким образом?
Меня не волнует, каковы исходные намерения отцов-основателей в отношении Конституции США. Меня не волнуют неписаные некодифицированные намерения. Меня волнует только то, что буквально кодифицировано в писаной Конституции, и как я могу использовать их для эффективного функционирования общества.
Меня волнует только то, что позволяют мне спецификации языка / платформы Java, и я намерен использовать их в полной мере, чтобы предоставить мне средство для эффективного и действенного выражения моих программных решений. Куртки не требуются.
Использование констант Enum на самом деле ужасная практика.
Требуется написать дополнительный код для сопоставления параметра со значением. Тот факт, что основатели Java не предусмотрели сопоставление значений параметров без вашего написания кода сопоставления, демонстрирующего константы Enum, является таким же непреднамеренным использованием языка Java.
Тем более, что вам не рекомендуется нормализовать и разбивать на компоненты ваши параметры, может возникнуть ложное впечатление, что параметры, смешанные в сумке Enum, принадлежат одному и тому же измерению.
Константы - это API Contract
Не забывай об этом. Если вы разработали и нормализовали свою модель данных, и они включают константы, то эти константы являются контрактами. Если вы не нормализовали свою модель данных, вы должны соответствовать фетвам о том, как применять ограничительное кодирование, чтобы справиться с этой вредной привычкой.
Следовательно, интерфейсы - идеальный способ реализации контракта констант.
Странное предположение - что, если интерфейс случайно будет реализован.
Ага. Кто угодно может непреднамеренно реализовать любой интерфейс. Таким непреднамеренным программистам ничто не помешает.
Разработайте и нормализуйте вашу модель данных против утечки
Не размещайте ограничительные указы для защиты предполагаемых недобросовестных действий, вызывающих утечку несогласованных / ошибочных параметров в API. Решите фундаментальную проблему, а не возлагайте вину на константы интерфейса.
Не использовать IDE - плохая практика
Нормально функционирующий и ЭФФЕКТИВНЫЙ программист не может доказать, как долго он может оставаться под водой, как далеко он может пройти в условиях сильной жары или влажных гроз. Она должна использовать эффективный инструмент, такой как автомобиль, автобус или, по крайней мере, велосипед, чтобы каждый день добираться на работу 10 миль.
Не накладывайте ограничений на коллег-программистов только потому, что вы страдаете эзотерическим аскетизмом и одержимы программированием без IDE.
Пара фреймворков призвана помочь программистам продолжать эффективно практиковать вредные привычки.
OSGI - это такая основа. И то же самое - указ против интерфейсных констант.
Поэтому окончательный ответ ...
Константы интерфейса - это эффективный и действенный способ разместить в Contract хорошо спроектированные и нормализованные компоненты модели данных.
Константы интерфейса в частном интерфейсе с соответствующим именем, вложенном в файл класса, также являются хорошей практикой для группировки всех ваших частных констант, а не разбрасывания их по всему файлу.
источник
Я несколько раз сталкивался с этим старым вопросом, и принятый ответ до сих пор меня смущает. После долгих размышлений, я думаю, этот вопрос можно прояснить.
Зачем использовать константу интерфейса?
Просто сравните их:
против
То же использование. Гораздо меньше кода.
Плохая практика?
Я думаю, что в ответе @Pascal Thivent неправильный акцент, вот моя версия:
Цитата из Effective Java предполагает, что постоянный интерфейс реализуется другими, чего, я думаю, не должно (и не будет).
Когда вы создаете постоянный интерфейс, названный чем-то вроде
Constants
, его никто не должен реализовывать. (хотя технически возможно, и это единственная проблема)Этого не будет в стандартной библиотеке
Стандартная библиотека не может позволить себе возможное неправильное использование дизайна, поэтому вы просто не увидите там ничего.
Тем не менее , для ежедневных проектов нормальных разработчиков, использующих интерфейс констант намного проще , потому что вам не нужно беспокоиться о
static
,final
,empty constructor
и т.д., и это не вызовет каких - либо плохой вопрос дизайна. Единственный недостаток, о котором я могу думать, это то, что у него все еще есть название «интерфейс», но не более того.Бесконечные дебаты
В конце концов, я думаю, что все просто цитируют книги, высказывают мнения и оправдывают свои позиции. Для меня не исключение. Возможно, решение остается за разработчиками каждого проекта. Просто используйте его, если чувствуете себя комфортно. Лучшее, что мы можем сделать, - это сделать его последовательным на протяжении всего проекта .
источник
public
также может быть опущен, поскольку это интерфейс, что делает его простым.double PI = 3.14159;
ИспользованиеConstants.PI
не требует использования класса для реализацииConstants
интерфейса! Я думаю, что интерфейсный подход намного чище с точки зрения использования, ИМХОДжошуа Блох, «Эффективная Java - Руководство по языку программирования»:
источник
Они полезны, если у вас есть общие константы, которые будут использоваться в классах, реализующих интерфейс.
Вот пример: http://www.javapractices.com/topic/TopicAction.do?Id=32
Но учтите, что рекомендуется использовать статический импорт вместо констант в интерфейсах. Вот ссылка: http://www.javapractices.com/topic/TopicAction.do?Id=195
источник
Есть очень разумные ответы.
Но у меня есть некоторые мысли по этому поводу. (может ошибаться)
На мой взгляд, поля в интерфейсе не должны быть константами для всего проекта, они являются только средствами для интерфейса, и интерфейсы расширяют его, а также классы, которые реализуют эти интерфейсы или имеют с ними тесную связь. Их следует использовать в пределах определенного диапазона, а не глобального.
источник
Два момента об интерфейсе:
Интерфейс описывает подмножество того, что может делать объект, который его реализует. (Это интуиция)
Интерфейс описывает общие константы, за которыми следуют объекты, которые его реализуют.
Поэтому я думаю, что если интерфейс констант не используется для глобальных констант , то это приемлемо:
implements
его (и, конечно же, используйте эти общие константы в реализации).Пример:
В этом примере:
Circle implements Drawable
, вы сразу знаете, чтоCircle
это, вероятно, соответствует константам, определенным вDrawable
, в противном случае им придется выбрать худшее имя, чем хорошие,PI
иGOLDEN_RATIO
уже было взято!Drawable
объекты соответствуют конкретнымPI
иGOLDEN_RATIO
определенным вDrawable
, могут быть объекты неDrawable
с разной точностью пи и золотого сечения.источник
javax.swing.SwingConstants
Интерфейс является примером , который получил статические поля , которые используются среди колеблющихся классов. Это позволяет вам легко использовать что-то вродеthis.add(LINE_START, swingcomponent);
this.add(this.LINE_START, swingcomponent);
илиthis.add(SwingComponents.LINE_START, swingcomponent);
Однако в этом интерфейсе нет методов ...
источник
Я наткнулся на этот вопрос и подумал, что добавлю кое-что, о чем не упоминалось. В общем, я согласен с ответом Паскаля здесь . Однако я не думаю, что константы в интерфейсе «всегда» антипаттерны.
Например, если константы, которые вы определяете, являются частью контракта для этого интерфейса, я думаю, что интерфейс - отличное место для констант. В некоторых случаях просто нецелесообразно проводить частную проверку ваших параметров, не раскрывая контракт пользователям вашей реализации. Без публичного контракта пользователи могут только догадываться, с чем вы выполняете проверку, за исключением декомпиляции класса и чтения вашего кода.
Итак, если вы реализуете интерфейс, и интерфейс имеет константы, которые вы используете для обеспечения своих контрактов (например, целочисленные диапазоны), то пользователь вашего класса может быть уверен, что они правильно используют экземпляр интерфейса, проверяя константы в интерфейсе. самих себя. Это было бы невозможно, если бы константы были частными для вашей реализации или если бы ваша реализация была частным пакетом или что-то в этом роде.
источник
Я использую константы интерфейса при работе с общими константами между классами.
Группировка - огромный плюс, особенно с большим набором констант.
Чтобы использовать, вы просто соединяете их вместе:
источник
Источник: Java Developer Tools Coding Style
источник