2009-08-12 7 views
10

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

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

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

ответ

12

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

  1. ... неизменны - глобальный, final/readonly ссылка на изменяемый объект (например, Java ArrayList<T> или C# List<T>) - это не постоянное, а глобальное состояние.
  2. ... необходимо> 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#, что мы имеем дело с - мы есть поставить наши константы где-то, и наш лучший вариант оказывается неинтуитивным классом.

25

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

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

5

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

То, что я хотел бы предложить, если вам нужно такие вещи, как это создать перечисления (в случае, если у вас есть Int константа) или статические классы для констант, так что вы можете дать им некоторый контекст (Math.PI, например)

0

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

+1

Да, но я спрашиваю о глобальных * константах * на самом деле. – aberrant80

+0

Какие шаблоны проектирования используют глобальные константы? – SwDevMan81

+0

Он говорит об анти-паттерне. –

7

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

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

+0

Проблемы с глобалами объясняются здесь: https://softwareengineering.stackexchange.com/a/262972/44844 – Katapofatico

4

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

+1

, если значение изменяется часто, его значение не является константой :) – gbjbaanb

+2

Я имею в виду, что * programmer * часто меняет значение, а не меняет значение во время выполнения. –

+0

постоянный для жизни одного исполнения программы мог бы сделать. Для очень продолжительного процесса я предполагаю, что Entropy получит его в конце, хотя :-( – djna

2

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

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

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

+0

У файлов конфигурации/свойств есть еще одно преимущество - гораздо быстрее искать в них текст (когда вам нужно переименовать окно, метку например). –

Смежные вопросы