Глобальные константы не плохая практика, до тех пор, как они ...
- ... неизменны - глобальный,
final
/readonly
ссылка на изменяемый объект (например, Java ArrayList<T>
или C# List<T>
) - это не постоянное, а глобальное состояние.
- ... необходимо> 1 класс. Если только один класс нуждается в ваших константах, поместите константы непосредственно в класс. (Оговорка: Баланс DRY против YAGNI соответственно.)
Блох покрывает «постоянный интерфейс» по сравнению с проблемой «постоянного класса» в «Эффективной Java» и выступает за подход «постоянного класса». Причина, по которой вам не нужны константы в интерфейсе, заключается в том, что он побуждает клиентские классы «реализовывать» этот интерфейс (чтобы получить доступ к константам без префикса их с именем интерфейса).Однако вы не должны - интерфейс фактически не является интерфейсом к возможностям объекта, а удобством компиляции, укоренившимся в внешнем типе класса. Рассмотрим это:
interface C { public static final int OMGHAX = 0x539; }
class A implements C { ... }
class B { private A a; }
Класс B
Теперь ненужно имеет зависимость к C
. Если реализация A
изменяется так, что она не нуждается в константах от C
, вы не можете удалить из нее implements C
, не нарушая ее внешний интерфейс - кто-то (возможно, очень глупый человек, но такие люди изобилуют) может ссылаться на объект A
через ссылку C
!
Поставив константы в класс и сделав этот класс неинстантируемым, вы сообщаете клиентам, что постоянный класс действительно просто функционирует как пространство под-имен. В C# вы отмечаете класс как static
, в Java вы хотите, чтобы сделать его final
и дать недостижимый конструктор:
final class C {
private C() { throw new AssertionError("C is uninstantiable"); }
public static final int OMGHAX = 0x539;
}
Если вы программируете на Java и хотите константы без префиксов их с именем постоянного класса, вы можете использовать функциональность import static
.
И да, это немного излишним вынуждены создать новый тип просто куда-то положить константы, но это бородавка на таких языках, как Java и C#, что мы имеем дело с - мы есть поставить наши константы где-то, и наш лучший вариант оказывается неинтуитивным классом.
Да, но я спрашиваю о глобальных * константах * на самом деле. – aberrant80
Какие шаблоны проектирования используют глобальные константы? – SwDevMan81
Он говорит об анти-паттерне. –