Dove dovresti mettere le costanti e perché?

26

Nelle nostre applicazioni per lo più di grandi dimensioni, di solito abbiamo solo poche posizioni per le costanti:

  • Una classe per GUI e contstant interni (titoli di pagine di schede, titoli di caselle di gruppo, fattori di calcolo, enumerazioni)
  • Una classe per le tabelle e le colonne del database (questa parte è codice generato) più i nomi leggibili per loro (assegnati manualmente)
  • Una classe per i messaggi dell'applicazione (registrazione, caselle di messaggi, ecc.)

Le costanti sono solitamente 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 si trovano in un posto centrale e tutti sanno dove trovarle quando qualcosa deve essere cambiato.

Questo è soprattutto un aspetto che i project manager amano 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 modificare facilmente il titolo di simili caselle di gruppo / pagine di tabulazioni contemporaneamente. Un altro aspetto è che puoi semplicemente stampare quella classe e darla a un non programmatore che può controllare se le didascalie sono intuitive e se i messaggi all'utente sono troppo dettagliati o troppo confusi ecc.

Tuttavia, vedo alcuni svantaggi:

  • Ogni singola classe è strettamente accoppiata alle classi di costanti
  • Aggiunta / rimozione / ridenominazione / spostamento di una costante richiede la ricompilazione di almeno il 90% dell'applicazione (Nota: la modifica del valore non lo fa, 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 che siano circa 50 minuti) più 10 minuti circa di collegamento con determinate librerie statiche.
  • La creazione di una versione ottimizzata per la velocità tramite Visual Studio Compiler richiede fino a 3 ore. Non so se l'enorme quantità di relazioni di classe è la fonte, ma potrebbe anche essere.
  • Si arriva direttamente al codice delle stringhe hard-coding perché si vuole testare qualcosa molto velocemente e non si vuole aspettare 15 minuti solo per quel test (e probabilmente ogni successivo). Tutti sanno cosa succede al "Lo aggiusterò più tardi" - pensieri.
  • Riusare una classe in un altro progetto non è sempre così facile (principalmente a causa di altri accoppiamenti stretti, ma la gestione delle costanti non rende più semplice.)

Dove memorizzereste costanti come quelle? Inoltre quali argomenti porteresti per convincere il tuo project manager che ci sono concetti migliori che rispettano anche i vantaggi sopra elencati?

Sentiti libero di dare una risposta specifica o indipendente al C ++.

PS: So che questa domanda è soggettiva, ma onestamente non conosco nessun posto migliore di questo sito per questo tipo di domanda.

Aggiornamento su questo progetto

Ho notizie sulla cosa in fase di compilazione:
Seguendo i post di Caleb e di gbjbaanb, ho diviso il mio file delle costanti in molti altri file quando avevo tempo. Alla fine ho anche diviso il mio progetto in diverse librerie che ora era possibile molto più facile. La compilazione di questo in modalità di rilascio ha mostrato che il file generato automaticamente che contiene le definizioni del database (tabella, nomi di colonne e altro - più di 8000 simboli) e crea determinati 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 !

Non abbiamo ancora trovato il motivo per cui MSVC ha difficoltà a ottimizzare questi file, ma per ora questo cambiamento allevia molta pressione dato che non dobbiamo più fare affidamento solo su build notturne.

Questo fatto - e altri vantaggi, come un accoppiamento meno stretto, una migliore riutilizzabilità, ecc. - mostrava anche che passare del tempo a suddividere le "costanti" non era affatto una cattiva idea; -)

    
posta Tim Meyer 19.04.2012 - 14:02
fonte

4 risposte

19

Le costanti specifiche di una classe dovrebbero andare nell'interfaccia di quella classe.

Le costanti che sono realmente opzioni di configurazione dovrebbero far parte di una classe di configurazione. Se fornisci accessor per le opzioni di configurazione in quella classe (e le usi al posto delle costanti altrove), non dovrai ricompilare il mondo intero quando cambi alcune opzioni.

Le costanti che sono condivise tra classi ma che non devono essere configurabili dovrebbero essere ragionevolmente circoscritte, provare a scomporle in file che hanno usi particolari in modo che le singole classi includano solo ciò di cui hanno effettivamente bisogno. Questo di nuovo aiuterà a ridurre i tempi di compilazione quando cambi alcune di quelle costanti.

    
risposta data 19.04.2012 - 19:00
fonte
5

Direi semplicemente che vuoi dividere la tua enorme classe di costanti in molti file più piccoli, uno per modulo, per esempio. Ciò garantisce che non si abbia una dipendenza così grande sul file delle costanti, quindi l'aggiunta o l'aggiornamento di una stringa non richiederebbe una ricompilazione totale. È comunque possibile memorizzare questi file in una posizione centrale, ma (ad es.) Avere 1 file con costanti per ogni finestra di dialogo, opportunamente denominata. Quindi puoi includere questi file solo nei file di dialogo pertinenti, che riducono la ricompilazione in modo massivo.

Suggerisco anche di usare qualcosa come le utility GNU GetText per gestire le stringhe, è progettato per la traduzione, ma funziona altrettanto bene semplicemente cambiando il testo in qualcos'altro. Potresti metterli in una risorsa di stringhe, ma trovo che sia più difficile lavorare con loro dato che sono codificati da ID, gli utilit di GetText sono imperniati su una stringa originale - rende le cose molto facili da sviluppare.

    
risposta data 19.04.2012 - 15:27
fonte
2

Nota: non sono uno sviluppatore C ++ ... ma ecco il mio pensiero: È necessario considerare il seguente commento di @jk sulla differenza tra l'utilizzo dei file di configurazione. In DotNet, ci sono file di risorse che vengono utilizzati per memorizzare tali informazioni. In Windows Form, un file di risorse viene gestito da VS per ogni modulo.

Non vedo un valore per cui una costante deve essere collocata al di fuori del suo ambito di utilizzo a meno che non sia una costante globale che deve essere condivisa. Come hai detto, questo sarà difficile da mantenere almeno durante lo sviluppo. Inoltre, potresti avere scontri sul nome. Un'altra cosa è che potrebbe essere difficile sapere chi sta usando una determinata costante.

Ora, se vuoi che il non programmatore riveda le informazioni, per la GUI puoi catturare lo schermo per loro. Se si desidera che rivedano le voci della tabella di dati, è possibile esportare i dati in Excel o qualcosa di simile.

Se si desidera continuare con un approccio di localizzazione centralizzato e si desidera posizionare tutte le costanti in un unico file di grandi dimensioni, ogni sviluppatore può utilizzare un file condiviso che viene aggiornato alla fine di ogni intervallo in un file centrale. I dati verranno dai singoli file utilizzati nello sviluppo. Questo può essere facilmente automatizzato o fatto manualmente. Tuttavia, come ho detto, probabilmente è un rischio che non devi prendere.

    
risposta data 19.04.2012 - 14:25
fonte
1

Suggerirei di inserire tutte queste costanti in una sorta di file di configurazione. Per le applicazioni Java, di solito utilizziamo i file .properties, un testo semplice con ogni riga formattata come "(chiave) = (valore)". Esempio

MainPanel.Title = Welcome to our application
DB.table.users = TBL_USERS
logging.filename = application.log

Quindi si carica questo file in fase di runtime, si popola una cache che consente di cercare una chiave e recuperare un valore. Quando hai bisogno di una costante, interroghi la cache. Avrai comunque bisogno di avere le tue chiavi da qualche parte, e la cache dovrà essere accessibile a livello globale, ma quando cambi i valori delle costanti, non è necessario ricompilare, dovrebbe essere possibile -Avviare l'app (o se si vuole davvero avere fantasia, avere più file .properties e cache e dare all'applicazione la possibilità di ricaricare una cache in fase di esecuzione).

Per un'implementazione, ho trovato questa domanda SO: link (è stato il primo hit di una ricerca su Google - non ho usato questo software personalmente)

    
risposta data 19.04.2012 - 16:29
fonte

Leggi altre domande sui tag