Nelle nostre applicazioni per lo più grandi, di solito abbiamo solo alcune posizioni per "costanti":
- Una classe per GUI e costanti interni (titoli delle schede, titoli delle caselle di gruppo, fattori di calcolo, enumerazioni)
- Una classe per tabelle e colonne di database (questa parte è generata da codice) più nomi leggibili per loro (assegnati manualmente)
- Una classe per i messaggi dell'applicazione (registrazione, finestre di messaggio ecc.)
Le costanti sono generalmente separate in diverse strutture in quelle classi. Nelle nostre applicazioni C ++, le costanti sono definite solo nel file .h e i valori sono assegnati nel file .cpp.
Uno dei vantaggi è che tutte le stringhe ecc. Sono in un posto centrale e tutti sanno dove trovarle quando qualcosa deve essere cambiato.
Questo è in particolare qualcosa che i project manager sembrano apprezzare quando le persone vanno e vengono e in questo modo tutti possono cambiare cose così banali senza dover scavare nella struttura dell'applicazione.
Inoltre, puoi facilmente cambiare il titolo di simili Caselle di gruppo / Pagine di schede ecc. Contemporaneamente. Un altro aspetto è che puoi semplicemente stampare quella classe e consegnarla a un non programmatore che può verificare se i sottotitoli sono intuitivi e se i messaggi per l'utente sono troppo dettagliati o troppo confusi ecc.
Tuttavia, vedo alcuni svantaggi:
- Ogni singola classe è strettamente accoppiata alle classi delle costanti
- L'aggiunta / rimozione / ridenominazione / spostamento di una costante richiede la ricompilazione di almeno il 90% dell'applicazione (Nota: la modifica del valore no, almeno per C ++). In uno dei nostri progetti C ++ con 1500 classi, ciò significa circa 7 minuti di tempo di compilazione (utilizzando intestazioni precompilate; senza di essi è di circa 50 minuti) più circa 10 minuti di collegamento con determinate librerie statiche.
- La creazione di una versione ottimizzata per la velocità tramite il compilatore di Visual Studio richiede fino a 3 ore. Non so se l'enorme quantità di relazioni di classe sia la fonte, ma potrebbe anche esserlo.
- Vieni guidato in stringhe temporaneamente hard-coding direttamente nel codice perché vuoi testare qualcosa molto rapidamente e non vuoi aspettare 15 minuti solo per quel test (e probabilmente tutti quelli successivi). Tutti sanno cosa succede al pensiero "Risolverò più tardi".
- Riutilizzare una classe in un altro progetto non è sempre così facile (principalmente a causa di altri accoppiamenti stretti, ma la gestione delle costanti non lo rende più facile).
Dove vorresti conservare costanti del genere? Inoltre, quali argomenti porteresti per convincere il tuo project manager che esistono concetti migliori che soddisfano anche i vantaggi sopra elencati?
Sentiti libero di dare una risposta C ++ specifica o indipendente.
PS: So che questa domanda è un po 'soggettiva, ma sinceramente non conosco un posto migliore di questo sito per questo tipo di domanda.
Aggiornamento su questo progetto
Ho notizie sulla cosa del tempo di compilazione:
seguendo i post di Caleb e gbjbaanb, quando ho avuto il tempo ho diviso il mio file delle costanti in molti altri file. Alla fine ho anche diviso il mio progetto in diverse librerie che ora era molto più semplice. Compilando questo in modalità di rilascio è emerso che il file generato automaticamente che contiene le definizioni del database (tabella, nomi delle colonne e altro - più di 8000 simboli) e crea alcuni hash ha causato enormi tempi di compilazione in modalità di rilascio.
La disattivazione dell'ottimizzatore di MSVC per la libreria che contiene le costanti DB ora ci ha permesso di ridurre il tempo di compilazione totale del tuo progetto (diverse applicazioni) in modalità di rilascio da un massimo di 8 ore a meno di un'ora!
Dobbiamo ancora scoprire perché MSVC ha difficoltà a ottimizzare questi file, ma per ora questo cambiamento allevia molta pressione poiché non dobbiamo più fare affidamento solo su build notturne.
Questo fatto - e altri benefici, come un accoppiamento meno stretto, una migliore reuseabilità ecc. - hanno anche mostrato che passare del tempo a dividere le "costanti" non era poi una cattiva idea ;-)
Update2
Dato che questa domanda riceve ancora qualche attenzione:
ecco cosa ho fatto negli ultimi anni:
Inserisci ogni costante, variabile, ecc. Esattamente nell'ambito che è pertinente per essa: se usi una costante solo in un singolo metodo, è OK definirla in quel metodo. Se una singola classe è interessata, lasciala come dettaglio di implementazione privato di quella classe. Lo stesso vale per lo spazio dei nomi, il modulo, il progetto, l'ambito aziendale. Uso anche lo stesso modello per le funzioni di supporto e simili. (Questo potrebbe non applicarsi al 100% se si sviluppa un framework pubblico.)
In questo modo aumenta la riusabilità, la testabilità e la manutenibilità in misura tale da non solo dedicare meno tempo alla compilazione (almeno in C ++), ma anche meno tempo alla correzione dei bug, che ti lascia più tempo per sviluppare effettivamente nuove funzionalità. Allo stesso tempo, lo sviluppo di queste funzionalità sarà più veloce poiché puoi riutilizzare più codice più facilmente. Ciò supera di gran lunga qualsiasi vantaggio il file delle costanti centrali potrebbe avere.
Dai un'occhiata in particolare al principio di segregazione dell'interfaccia e al principio di responsabilità singola se vuoi saperne di più.
Se sei d'accordo, vota la risposta di Caleb poiché questo aggiornamento è sostanzialmente una visione più generale di ciò che ha detto.