У наших переважно великих програмах ми зазвичай маємо лише кілька місць для "констант":
- Один клас для графічного інтерфейсу та внутрішніх константів (заголовки сторінки вкладок, заголовки групи, обчислювальні фактори, перерахування)
- Один клас для таблиць та стовпців бази даних (ця частина генерується кодом) плюс читабельні назви для них (призначається вручну)
- Один клас для повідомлень програми (ведення журналів, скриньки повідомлень тощо)
Константи зазвичай розділені на різні структури в цих класах. У наших додатках C ++ константи визначаються лише у файлі .h, а значення призначаються у файлі .cpp.
Однією з переваг є те, що всі рядки тощо знаходяться на одному центральному місці, і всі знають, де їх знайти, коли щось потрібно змінити.
Це особливо те, що, як здається, подобається керівникам проектів, коли люди приходять і йдуть, і таким чином кожен може змінити такі дрібниці, не вникаючи в структуру програми.
Крім того, ви можете легко змінити заголовок подібних групових скриньок / сторінок вкладок тощо. Інший аспект полягає в тому, що ви можете просто роздрукувати цей клас і надати його непрограмісту, який може перевірити, чи підписи є інтуїтивними, а також якщо повідомлення користувачеві надто детальні чи занадто заплутані тощо.
Однак я бачу певні недоліки:
- Кожен окремий клас щільно поєднаний з константними класами
- Додавання / видалення / перейменування / переміщення константи вимагає перекомпіляції щонайменше 90% програми (Примітка. Зміна значення не принаймні для C ++). В одному з наших проектів на C ++ з 1500 класами це означає близько 7 хвилин часу компіляції (використовуючи попередньо складені заголовки; без них - близько 50 хвилин), а також близько 10 хвилин зв’язку з певними статичними бібліотеками.
- Створення оптимізованої швидкості випуску через компілятор Visual Studio займає до 3 годин. Я не знаю, чи джерело величезних класових відносин, але це може бути.
- Ви потрапляєте в тимчасово жорсткі кодування рядків прямо в код, тому що ви хочете тестувати щось дуже швидко і не хочете чекати 15 хвилин лише для цього тесту (і, мабуть, кожного наступного). Всім відомо, що станеться з думками "Я це виправлю пізніше".
- Повторне використання класу в іншому проекті не завжди є таким простим (головним чином, завдяки іншим тісним муфтам, але керування константами не спрощує.)
Де б ви зберігали такі константи? Також які аргументи ви б навели, щоб переконати свого керівника проекту в тому, що існують кращі концепції, які також відповідають переліченим вище перевагам?
Сміливо дайте відповідь на C ++ - конкретну чи незалежну.
PS: Я знаю, що це питання є певним суб'єктивним, але я, чесно кажучи, не знаю жодного кращого місця, ніж цей сайт для такого роду питань.
Оновлення цього проекту
У мене є новини про час збирання:
Після публікацій Калеба та gbjbaanb я розділив свій файл констант на кілька інших файлів, коли встиг. Я також врешті-решт розділив свій проект на кілька бібліотек, що стало можливо набагато простіше. Компіляція цього в режимі випуску показала, що автоматично згенерований файл, який містить визначення бази даних (таблиця, назви стовпців та більше - понад 8000 символів) та накопичує певні хеші, спричинив величезний час компіляції у режимі випуску.
Дезактивація оптимізатора MSVC для бібліотеки, яка містить константи БД, тепер дозволила нам скоротити загальний час компіляції вашого проекту (кілька програм) у режимі випуску з 8 годин до менш ніж однієї години!
Ми ще не з'ясували, чому MSVC настільки важко оптимізує ці файли, але наразі ця зміна знімає сильний тиск, оскільки нам більше не доводиться покладатися лише на нічні побудови.
Цей факт - а також інші переваги, такі як менш жорстке з'єднання, краща повторність використання тощо - також показали, що витрачати час на розбиття «констант» все-таки не така погана ідея ;-)
Оновлення2
Оскільки це питання все ще привертає певну увагу:
ось що я робив за останні кілька років:
Поставити кожну константу, змінну тощо точно в ту область, яка для неї є актуальною: Якщо ви використовуєте константу лише в одному методі, визначити її в цьому методі добре. Якщо один клас зацікавлений у ньому, залиште його як приватну детальну інформацію про цей клас. Те саме стосується простору імен, модуля, проекту, сфери діяльності компанії. Я також використовую ту саму схему для допоміжних функцій тощо. (Це може не застосовуватися на 100%, якщо ви розробляєте загальнодоступні рамки.)
Це збільшує багаторазове використання, тестуваність та ремонтопридатність до такої міри, коли ви не тільки витрачаєте менше часу на компіляцію (принаймні, на C ++), але і менше часу на виправлення помилок, що залишає вам більше часу для фактичного розвитку нових функцій. У той же час, розробка цих функцій піде швидше, оскільки ви можете використовувати більше коду легше. Це переважає будь-яку перевагу, яку може мати файл центральних констант на величину.
Подивіться особливо на принцип сегрегації інтерфейсу та принцип єдиної відповідальності, якщо хочете дізнатися більше.
Якщо ви згодні, підтримайте відповідь Калеба, оскільки це оновлення в основному є більш загальним питанням щодо того, що він сказав.