Я пишу набор тестовых классов junit на Java. Есть несколько констант, например, строки, которые мне понадобятся в разных тестовых классах. Я думаю об интерфейсе, который определяет их, и каждый тестовый класс будет реализовывать его.
Я вижу здесь следующие преимущества:
- легкий доступ к константам:
MY_CONSTANT
вместоThatClass.MY_CONSTANT
- каждая константа определена только один раз
Этот подход - хорошая или плохая практика? Я чувствую, что немного злоупотребляю концепцией интерфейсов.
Вы можете ответить в основном об интерфейсах / константах, но также и о модульных тестах, если есть что-то особенное в этом.
java
design
programming-practices
constants
FabianB
источник
источник
Ответы:
Джошуа Блох советует против этого в своей книге « Эффективная Java» :
Вы можете получить тот же эффект с обычным классом, который определяет константы, а затем использовать
import static com.example.Constants.*;
источник
В нашем случае мы делаем это, потому что значения констант представляют контракт для конечных состояний, которые требуется предоставить реализации сервиса. Помещение этих констант в интерфейс указывает конечные состояния как часть контракта, и если бы любая реализация интерфейса не использовала их, это не сделало бы свою работу.
НЕКОТОРЫЕ константы являются деталями реализации. ИНОГДА они не. Как обычно, инженер должен использовать свой мозг, чтобы решить, что делать, а не полагаться на развернутый шаблон или практику.
источник
Я не думаю, что хорошо иметь интерфейсы только для констант.
Но если интерфейс, который определяет поведение (методы, реализующие классы должны реализовывать), имеет константы, это нормально. Если он «пропускает некоторые детали разработчика» в API, это потому, что так оно и должно быть. Они также сообщают, что разработчик реализует методы foo и bar.
Взять, к примеру, интерфейс java.awt.Transparency. Он имеет константы OPAQUE, BITMASK и TRANSLUCENT, но также имеет метод getTransparency ().
Если дизайнер поместил эти константы туда, это потому, что он / она думал, что он будет достаточно стабильным, чтобы быть частью интерфейса, как getTransparency ().
источник
Думаю, это точка зрения, наиболее популярная в тех местах, где дизайн по контракту преобладает.
Интерфейсы являются контрактами. Размещение констант в интерфейсах означает, что каждый класс, который соблюдает контракт, соглашается со значением / концепцией, определенной константой.
источник
"at most expose their names"
, не раскрывая значения?Компания, в которой я работал, интенсивно использовала импортированные интерфейсом 1 константы. Я не чувствую никакого вреда от этого.
Вопрос, который вы должны задать себе: насколько важно для вас пространство имен? В случае констант, это действительно все, что действует класс. Если у вас есть тысячи констант, вы можете не хотеть, чтобы все эти константы были всегда доступны.
Крутая вещь об интерфейсах - это то, что она дает вам преимущество работы в любом случае - вводите все необходимые вам пространства имен или ни одного из них (и обращайтесь к ним явно, с помощью
MyInterface.CONSTANT
). Почти то же самоеimport static MyInterface.*
, но немного более очевидно.1: Если вы не знакомы с Java, я не имею в виду
import
ключевое слово, я просто имею в виду привезены черезimplements MyConstantsInterface
источник
Я родом из прошлого, который в основном зависит от «пути Ады» и «пути .Net». Я бы сказал нет, что, вероятно, не лучше объявлять константы в интерфейсах. Это технически не разрешено в c #.
Причина, по которой я говорю «нет», заключается в том, что интерфейс - это форма контракта, которая определяет поведение, а не состояние или структуру. Константа подразумевает какое-то состояние (примитив) или аспект состояния (составной или совокупный).
Я могу оценить стремление сделать значения по умолчанию и предопределенные значения доступными для всех, кто реализует интерфейс, но, возможно, состояние по умолчанию лучше было бы описать в абстрактном объекте или объекте значения или шаблоне, где значения по умолчанию имели бы как минимум минимальный контекст.
Для более технического руководства: download.oracle.com/javase/1.5.0/docs/guide/language/static-import.html
источник
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import.
Отзыв от Oracle DocsНет, это не плохая практика.
Дело в том, что константы, как и любой другой артефакт, должны вводиться по правилам минимальной видимости и надлежащего уровня абстракции.
Использование синтаксиса только потому, что вы можете это настоящая проблема.
источник