È mai una buona idea codificare i valori nelle nostre applicazioni? O è sempre la cosa giusta chiamare questi tipi di valori dinamicamente nel caso in cui debbano essere modificati?

Commenti

  • un parametro di configurazione ti aiuterebbe
  • Non sai mai quando il valore di pi potrebbe cambiare …
  • Amico, immagino che persone come @gabe siano la ragione per cui è una ” regola “. Se ripeti 3.14 in 20 punti del codice e poi scopri che hai effettivamente bisogno di maggiore precisione, sei fregato. Non ‘ mi ero reso conto che non era ‘ ovvio.
  • È stato un po scortese, @ Bill. @Gabe stava chiaramente scherzando, ma a parte questo, la domanda riguardava lhardcoding e i parametri di configurazione, non luso di numeri magici costanti e ripetuti in più punti.
  • Sì, lhardcoding a volte può essere una buona idea . Consulta larticolo di Wikipedia sul ” Softcoding ” anti-pattern.

Rispondi

Sì, ma rendilo ovvio .

Sì:

  • usa costanti
  • usa un descrittivo nome della variabile

Non “t:

Commenti

  • Che è più pulito, diameter = 2 * radius o diameter = RADIUS_TO_DIAMETER_FACTOR * radius? In effetti ci sono casi estremi in cui un numero magico può essere una soluzione migliore.
  • Non posso ‘ essere daccordo con questa risposta è sufficiente. Tendo a pensare alla programmazione come se fossi un romanziere. Racconti la tua storia attraverso il codice e se le persone non riescono a capire la logica, secondo me il tuo codice diventa inutile. Questo ‘ Ecco perché convenzioni di denominazione ben ponderate sono essenzialmente per la leggibilità. Inoltre, non ci sono buone ragioni per usare numeri magici. Usando numeri magici rimuovi il ” perché ” dallequazione e renderlo più difficile da capire tand. Ad esempio: ” diametro = 2 * radius ” A cosa servono i due? Questo ” diametro = RADIUS_TO_DIAMETER_FACTOR * raggio ” ha molto più senso.
  • diametro = 2 * raggio è direttamente da matematica delle scuole superiori. Il motivo per non nominare ” 2 ” è che per avere un valore diverso da qualsiasi altra cosa richiederebbe una modifica alle leggi di fisica o matematica, o entrambi. (Daltra parte, nominare Pi, o costante di Plancks è una buona mossa per una semplice leggibilità).
  • @Joonas: Pfft. Sicuramente intendi diameter = radius << 1? Suppongo che potrebbe anche essere diameter = radius << RADIUS_TO_DIAMETER_BITS_TO_SHIFT.
  • come ‘ su alcuni diameter = radius.toDiameter()

Risposta

Cosa trovo strano di questo Q & Finora nessuno ha effettivamente tentato di definire chiaramente “hard-code” o, cosa più importante, le alternative.

tl; dr : Sì, è a volte una buona idea codificare i valori, ma non esiste una regola semplice per quando ; dipende completamente dal contesto.

La domanda la restringe a valori , che intendo significare numeri magici , ma la risposta al fatto che “siano una buona idea o meno è relativa a per cosa” vengono effettivamente utilizzati!

Diversi esempi di “hard-coded “i valori sono:

  • Valori di configurazione

    Rabbrividisco ogni volta che vedo dichiarazioni come command.Timeout = 600. Perché 600? Chi lha deciso? Prima era scaduto e qualcuno ha sollevato il timeout come hack invece di risolvere il problema di prestazioni sottostante? O è effettivamente unaspettativa nota e documentata per il tempo di elaborazione?

    Questi non dovrebbero essere numeri magici o costanti, dovrebbero essere esternalizzati in un file di configurazione o database da qualche parte con un nome significativo, perché il loro valore ottimale è determinato in gran parte o interamente dallambiente in cui è in esecuzione lapplicazione.

  • Formule matematiche

    Le formule di solito tendono ad essere piuttosto statiche, in modo che la natura dei valori costanti allinterno non sia particolarmente importante. Il volume di una piramide è (1/3) b * h. Ci interessa da dove viene l1 o il 3? Non proprio. Un commentatore precedente ha giustamente sottolineato che diameter = radius * 2 è probabilmente migliore di diameter = radius * RADIUS_TO_DIAMETER_CONVERSION_FACTOR, ma questa è una falsa dicotomia.

    Quello che dovresti fare per questo tipo di scenario è creare una funzione . Non ho bisogno di sapere come hai inventato la formula, ma ho ancora bisogno di sapere a cosa serve . Se, invece di una qualsiasi delle sciocchezze scritte sopra, scrivo volume = GetVolumeOfPyramid(base, height) allimprovviso tutto diventa molto più chiaro, ed è perfettamente normale avere numeri magici dentro la funzione (return base * height / 3) perché è ovvio che sono solo una parte della formula.

    La chiave qui è ovviamente avere funzioni brevi e semplici . Questo non funziona per funzioni con 10 argomenti e 30 righe di calcolo. Utilizza la composizione della funzione o le costanti in questo caso.

  • Dominio / regole aziendali

    Questa è sempre larea grigia perché dipende da quale sia esattamente il valore. La maggior parte delle volte, sono questi particolari numeri magici che sono candidati a trasformarsi in costanti, perché questo rende il programma più facile da capire senza complicare la logica del programma. Considera il test if Age < 19 e if Age < LegalDrinkingAge; probabilmente puoi capire cosa” sta succedendo senza la costante, ma è più facile con la descrizione titolo.

    Questi possono anche diventare candidati per lastrazione di funzioni, ad esempio function isLegalDrinkingAge(age) { return age >= 19 }. Lunica cosa è che spesso la tua logica aziendale è molto più complicato di così, e potrebbe non avere senso iniziare a scrivere dozzine di funzioni con 20-30 parametri ciascuna. Se non cè “unastrazione chiara basata su oggetti e / o funzioni, allora il ricorso a costanti è OK.

    Lavvertenza è che, se “lavori per il fisco, diventa davvero, davvero oneroso e onestamente inutile scrivere AttachForm(FORM_CODE_FOR_SINGLE_TAXPAYER_FILING_JOINTLY_FOR_DEPRECIATION_ON_ARMPIT_HAIR). Non lo farai t, stai andando a AttachForm("B-46") perché ogni singolo sviluppatore che abbia mai lavorato o lavorerà lì saprà che “B-46” è il codice del modulo per un singolo contribuente limatura blah blah blah – i codici del modulo fanno parte del dominio stesso, non cambiano mai, quindi “non sono davvero numeri magici.

    Quindi devi usare le costanti con parsimonia nella logica aziendale; fondamentalmente devi capire se quel “numero magico” è effettivamente un numero magico o se “è un aspetto ben noto del dominio. Se è il dominio, allora non lo codifichi in modo soft a meno che non ci sia” un ottime possibilità che cambi.

  • Codici di errore e flag di stato

    Questi non sono mai a posto per lhard-code, come può dirti qualsiasi povero bastardo che sia stato colpito con il Previous action failed due to error code 46. Se la tua lingua lo supporta, dovresti usare un tipo di enumerazione. Altrimenti, di solito avrai un intero file / modulo pieno di costanti che specificano i valori validi per un particolare tipo di errore.

    Non farmi mai vedere return 42 in un gestore di errori, capiche? Nessuna scusa.

Probabilmente ho tralasciato diversi scenari, ma penso che questo copra la maggior parte di essi.

Quindi, sì, a volte è una pratica accettabile per hard code roba. Basta non essere pigro su di esso; dovrebbe essere una decisione consapevole piuttosto che un semplice vecchio codice sciatto.

Commenti

  • Grazie per la buona analisi! – la maggior parte delle persone non ‘ pensa a tutte le opzioni che aggiungerei ” Configurazione ambiente ” – Penso che questi dovrebbero essere evitati (non hard-coded), poiché la maggior parte dei dati dovrebbe essere inserita in un file di configurazione o in un database. Questo segue il principio di ” mantenere separati i dati e la logica ” che è un pilastro di MVC o MVVM. stringa TestServerVar = ” foo “; string ProdServerVal = ” bar “;

Risposta

Esistono vari motivi per assegnare un identificatore a un numero.

  • Se il numero potrebbe cambiare, dovrebbe avere un identificatore. È molto più facile trovare NUMBER_OF_PLANETS che cercare ogni istanza di 9 e valutare se debba essere cambiato in 8. (Nota che visibile allutente le stringhe potrebbero dover cambiare se il software deve essere utilizzato in una lingua diversa, e questa “è una cosa difficile da prevedere in anticipo.)
  • Se il numero è difficile da digitare in alcun modo. Per costanti come pi, è meglio dare una definizione di massima precisione piuttosto che riscriverla in più punti, possibilmente in modo impreciso.
  • Se il numero si trova in posti diversi. Non dovresti prendere in considerazione due usi di 45 in funzioni adiacenti e chiederti se hanno la stessa cosa.
  • Se il significato non è immediatamente riconoscibile. È lecito ritenere che tutti sappiano cosa sia 3.14159265 … Non è lecito ritenere che tutti riconosceranno la costante gravitazionale, o anche pi / 2. (“Tutti” qui dipende dalla natura del software. Ci si può aspettare che i programmatori di sistema conoscano la rappresentazione ottale dei bit di autorizzazione Unix o simili. Nel software di architettura navale / marina, controllare il numero di Froude di uno scafo proposto e velocizzare vedere se “s 1.1 o superiore potrebbe essere perfettamente autoesplicativo per chiunque dovrebbe lavorarci).
  • Se il contesto non è riconoscibile . Tutti sanno che ci sono 60 minuti in unora, ma moltiplicare o dividere per 60 potrebbe non essere chiaro se non ci sono indicazioni immediate che la quantità sia un valore temporale o un valore di tariffa .

Questo ci fornisce i criteri per i valori letterali hard-coding. Dovrebbero essere immutabili, non difficili da digitare, presenti in un solo luogo o contesto e con un significato riconoscibile. Non ha senso nel definire 0 come ARRAY_BEGINNING, ad esempio, o 1 come ARRAY_INCREMENT.

Risposta

Come aggiunta ad altre risposte. Usa costanti per le stringhe quando possibile. Ovviamente non vuoi avere

const string server_var="server_var"; 

ma dovresti avere

const string MySelectQuery="select * from mytable;"; 

(supponendo che tu abbia effettivamente una query in cui vuoi ottenere tutti i risultati da una tabella specifica, sempre)

Oltre a questo, usa costanti per qualsiasi numero diverso da 0 (di solito). Se hai bisogno una maschera di bit di autorizzazione di 255, non utilizzare

const int 8th_bit=255; //or some other obscure naming scheme that equates to 255. 

invece utilizzare

const int AllowGlobalRead=255; 

Naturalmente, insieme alle costanti, sai quando usare gli enumeratori. Il caso precedente probabilmente si adatterebbe bene in uno.

Commenti

  • typedef enum {state_0 = 0, state_1 = 1, state_2 = 2, .. .} … Non ‘ ridere, ‘ lho visto fare. Colpisci quella persona in testa con un pesce bagnato!
  • @ velocemente bene, naturalmente ‘ vorresti qualcosa di più simile a typedef enum {init_state=0, parse_state=1, evaluation_state=2, ... }
  • THIS_NAMING_CONVENTION_IS_RECOMMENDED_FOR_CONSTANTS
  • Per le stringhe, non ‘ vuoi solo le costanti. Vuoi inserire qualsiasi stringa visibile allutente in una sorta di file di risorse (i dettagli dipenderanno dalla tua piattaforma) in modo da poter passare facilmente a unaltra lingua.
  • Potresti anche voler mantenere la logica aziendale stringhe (come le query SQL) in un file di risorse con un qualche tipo di crittografia o offuscamento. Ciò impedirà agli utenti ” curiosi ” di eseguire il reverse engineering della logica (o dello schema del database).

Risposta

Dipende da cosa si considera hardcoding. Se cerchi di evitare qualsiasi cosa codificata, finisci nel territorio del softcoding e crei un sistema che solo il creatore può gestire (e questo è il ultimate hardcode)

Molte cose sono codificate in qualsiasi framework ragionevole e funzionano. cioè non cè motivo tecnico per cui non dovrei essere in grado di cambiare il punto di ingresso di unapplicazione C # (static void Main ), ma un hardcoding che non crea problemi a nessun utente (eccetto la domanda SO )

La regola pratica che uso è che tutto ciò che può e cambierà, senza influenzare lo stato dellintero sistema, dovrebbe essere confugurabile.

Quindi, IMHO, è sciocco non codificare cose che non cambiano mai (pi, costante gravitazionale, una costante in una formula matematica – pensa al volume di una sfera).

Inoltre è sciocco non codificare cose o processi che avranno un impatto sul tuo sistema che richiederà programmazione in ogni caso, io .e. è uno spreco consentire allutente di aggiungere campi dinamici a un modulo, se qualsiasi campo aggiunto richiede allo sviluppatore della manutenzione di entrare e scrivere uno script che faccia funzionare quella cosa. Inoltre è stupido (e lho visto un paio di volte in ambienti aziendali) creare uno strumento di configurazione, quindi niente è hardcoded, tuttavia, solo gli sviluppatori del reparto IT possono usarlo ed è solo leggermente più facile usarlo piuttosto che farlo in Visual Studio.

Quindi, in conclusione, se una cosa deve essere codificata è una funzione di due variabili:

  • cambierà il valore
  • in che modo una modifica del valore influirà sul sistema

Risposta

È mai una buona idea codificare i valori nelle nostre applicazioni?

I valori hardcode solo se i valori sono specificati nella Specifica (in una versione finale della specifica), ad es. La risposta HTTP OK sarà sempre 200 (a meno che non cambi nella RFC), quindi vedrai (in alcuni dei miei codici) costanti come:

public static final int HTTP_OK = 200; 

Altrimenti, memorizzo le costanti nel file delle proprietà.

Il motivo per cui ho specificato le specifiche è che la modifica delle costanti nelle specifiche richiede la gestione delle modifiche, in cui, il le parti interessate esamineranno la modifica e approveranno / disapproveranno. Non accade mai dalloggi al domani e occorrono mesi / anni per lapprovazione. Non dimenticare che molti sviluppatori utilizzano specifiche (ad es. HTTP), quindi cambiarle significa rompere milioni di sistemi.

Answer

  • se il valore può cambiare, e in effetti potrebbe cambiare, allora codificalo in modo soft quando possibile purché lo sforzo richiesto non superi il rendimento atteso
  • alcuni valori non possono essere soft-coded; segui le linee guida di Jonathan in questi (rari) casi

Risposta

Ho “notato che ogni volta che puoi estrarre dati dal tuo codice, migliora ciò che resta. Inizi a notare nuovi refactoring e migliorare intere sezioni del tuo codice.

È solo una buona idea lavorare per estrarre le costanti, non considerarla una regola stupida, pensala come unopportunità per programmare meglio.

Il vantaggio più grande sarebbe il modo in cui potresti trovare costanti simili come lunica differenza nei gruppi di codice: astrarli in array mi ha aiutato a ridurre alcuni file del 90% della loro dimensione e risolverli abbastanza nel frattempo alcune copie & incolla bug.

Non ho ancora visto un unico vantaggio nel non estrarre dati.

Risposta

Recentemente ho codificato una funzione MySQL per calcolare correttamente la distanza tra due coppie lat / long. Non puoi semplicemente fare pitagora; le linee di longitudine si avvicinano allaumentare della latitudine verso i poli, quindi è coinvolta una specie di trigonometrica pelosa. Il punto è che ero piuttosto indeciso sullopportunità di codificare il valore che rappresenta il raggio della terra in miglia.

Ho finito per farlo, anche se il fatto è che le linee lat / lng sono molto più vicine tra loro, diciamo, sulla luna. E la mia funzione sottostimerebbe drasticamente le distanze tra i punti su Giove. Immaginavo che le probabilità che il sito web che sto costruendo abbia una posizione extraterrestre fosse piuttosto esigua.

Commenti

Risposta

Beh, dipende se il tuo linguaggio è compilato. Se non è compilato, non è un grosso problema, devi solo modificare il codice sorgente, anche se sarà leggermente delicato per un non programmatore.

Se stai programmando con un linguaggio compilato, questa chiaramente non è una buona idea, perché se le variabili cambiano, devi ricompilarlo, il che è una grande perdita di tempo se vuoi regolare questa variabile.

Non è necessario creare alcun cursore o interfaccia per modificare dinamicamente la sua variabile, ma il minimo che potresti fare è un file di testo.

Ad esempio con il mio progetto ogre, io uso sempre la classe ConfigFile per caricare una variabile che ho scritto in un file di configurazione.

Answer

Due occasioni in cui le costanti sono (almeno secondo me) OK:

  1. Costanti che non si riferiscono a nientaltro; puoi cambiare quelle costanti ogni volta che vuoi senza dover cambiare nientaltro. Esempio: la larghezza predefinita di una colonna della griglia.

  2. Costanti assolutamente immutabili, precise, ovvie, come “numero di giorni alla settimana”. days = weeks * 7 La sostituzione di 7 con una costante DAYS_PER_WEEK non fornisce quasi alcun valore.

Risposta

Sono completamente daccordo con Jonathan ma come tutte le regole ci sono delle eccezioni …

“Numero magico nella specifica: numero magico nel codice”

afferma sostanzialmente che qualsiasi numero magico che rimane nella specifica dopo tentativi ragionevoli di ottenere un contesto descrittivo per loro dovrebbe essere riflesso come tale nel codice. Se i numeri magici rimangono nel codice, ogni sforzo dovrebbe essere fatto per isolarli e renderli chiaramente collegati al loro punto di origine.

Ho eseguito alcuni contratti di interfacciamento in cui è necessario popolare i messaggi con valori mappati dal database. Nella maggior parte dei casi la mappatura è abbastanza semplice e si adatterebbe alle linee guida generali di Jonathan, ma ho riscontrato casi in cui la struttura del messaggio di destinazione era semplicemente orribile.Più dell80% dei valori che dovevano essere trasmessi nella struttura erano costanti applicate dalle specifiche del sistema distante. questo, unito al fatto che la struttura del messaggio era gigantesca, ha fatto sì che molte di queste costanti dovevano essere popolate. Nella maggior parte dei casi non fornivano un significato o una ragione, dicevano semplicemente “metti M qui” o “metti 4.10.53.10100.889450.4452 qui”. Non ho nemmeno tentato di mettere un commento accanto a tutti loro, avrebbe reso illeggibile il codice risultante. Tuttavia, mi sono assicurato che le sezioni di codice in cui compaiono questi valori magici siano adeguatamente isolate e che i loro contenitori (classi, pacchetti) denominati in modo appropriato per puntare direttamente alla specifica che li impone.

Detto questo, se ci pensi è … si tratta praticamente di renderlo ovvio

Risposta

Se stai “re codificando” il valore della costante gravitazionale terrestre, a nessuno importerà. Se codifichi lindirizzo IP del tuo server proxy, sei nei guai.

Commenti

  • Potresti aver bisogno di maggiore precisione per Earth ‘ s costante gravitazionale, quindi codificarla diverse volte potrebbe causare problemi.
  • Peter Noone? Da Herman ‘ s Hermits ?
  • Laccelerazione gravitazionale sulla Terra è praticamente di 9,81 m / s ^ 2 per la maggior parte delle latitudini e delle altitudini (ovviamente, se ‘ stai cercando petrolio sottoterra, o sparando a missili balistici intercontinentali sul Polo Nord, sapendo che la variazione di gravità è molto importante per molte più cifre decimali), con laccelerazione gravitazionale su altri pianeti che è un numero diverso, ma per quanto ne so, la costante gravitazionale è costante in tutto luniverso. Cè molta fisica che dovrebbe cambiare se g fosse variabile.

Risposta

Per lo più no, ma penso che valga la pena notare che lo farai Avrò la maggior parte dei problemi quando inizierai a duplicare il valore hardcoded. Se non lo duplichi (es. Usalo solo una volta nellimplementazione di una classe), allora non usare una costante potrebbe andare bene.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *