Являются ли глобальные константы анти-шаблоном?

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

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

Что думают другие люди?

7 ответов


глобальные константы не плохая практика, пока они есть...

  1. ... неизменный-глобальный,final/readonly ссылка на изменяемый объект (например, Java ArrayList<T> или C# List<T>) - это не постоянное, а глобальное состояние.
  2. ... нужны >1 класс. Если только один класс нуждается в ваших константах, поместите константы непосредственно в класс. (Предостережение: баланс сухой против YAGNI соответствующим образом.)

блох охватывает "постоянный интерфейс" против проблема " constant class "в эффективной Java и выступает за подход" constant class". Причина, по которой вы не хотите константы в интерфейсе, заключается в том, что он соблазняет клиентские классы "реализовать" этот интерфейс (для доступа к константам без префикса их с именем интерфейса). Однако вы не должны - интерфейс на самом деле не является интерфейсом возможностей объекта, а удобством во время компиляции, укоренившимся во внешнем типе класса. Считать это:

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 ссылка!

поставив константы в классе, и этот класс uninstantiable, вы сообщаете клиентам, что класс constant действительно просто функционирует как подпространство имен. В 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#, с которыми нам приходится иметь дело - we есть поставить наши константы где-то, и наш лучший вариант - это не инстанцируемый класс.


глобальные константы в порядке.

глобальные (непостоянные) переменные-это работа дьявола.


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

Я бы сказал, что истинно глобальные константы также проблематичны по той же причине, поэтому вместо того, чтобы иметь синглтон, называемый MyGlobals, содержащий константу, такую как MyGlobals.HTTP_SUCCESS_OK, пакет как константы вместе в своих собственных классах, таких как HttpStatus.SUCCESS_OK.


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

Я бы предложил, Если вам нужны такие вещи, как создание перечислений (если у вас есть константы int) или статические классы для констант, поэтому вы можете дать им некоторый контекст (математика.ПИ, например)


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


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

например, вы не хотели бы иметь несколько классов, каждый из которых объявляет свою собственную константу для pi, e или HTTP_SUCCESS.

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


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