Che cosa è un numero magico, e perché è di male?

Che cosa è un numero magico?

Perché dovrebbe essere evitato?

Ci sono casi in cui non è appropriato?

InformationsquelleAutor Adam Davis | 2008-09-06

 

15 Replies
  1. 541

    Un numero magico è un uso diretto di un numero in codice.

    Per esempio, se si dispone di (in Java):

    public class Foo {
        public void setPassword(String password) {
             //don't do this
             if (password.length() > 7) {
                  throw new InvalidArgumentException("password");
             }
        }
    }

    Questo dovrebbe essere rielaborato:

    public class Foo {
        public static final int MAX_PASSWORD_SIZE = 7;
    
        public void setPassword(String password) {
             if (password.length() > MAX_PASSWORD_SIZE) {
                  throw new InvalidArgumentException("password");
             }
        }
    }

    Migliora la leggibilità del codice, ed è più facile da mantenere. Immaginare il caso in cui ho impostato la dimensione del campo password nella GUI. Se io uso un numero magico, ogni volta che la dimensione massima modifiche, devo modificare nel codice di due posizioni. Se ho dimenticato uno, questo porterà ad incoerenze.

    JDK è piena di esempi di come in Integer, Character e Math classi.

    PS: strumenti di analisi Statica come FindBugs e PMD rileva l’utilizzo di numeri di magia nel codice e suggerisce il refactoring.

    • Nell’ .NET world, FxCop e il codice di Visual Studio 2008 metriche dovrebbe puntare per voi.
    • Così sono male e se sì perché?
    • 0 e 1 sono eccezioni a questa regola.
    • Dovrei scrivere: public static final HUNDRED_PERCENTS = 100; ?
    • Se si prevede che la definizione di “Cento Percento” a cambiare, allora sì. Un approccio migliore sarebbe quello di avere la variabile da ciò che è per quello che rappresenta, cioè, public static final MAX_DOWNLOAD_PERCENTAGE = 100. Anche se questo non avrebbe senso, perché “100 per cento” è molto ben definito. D’altra parte, il fatto che le Password possono essere un massimo di 7 caratteri non è definito a livello globale e in realtà è diverso, in modo che è un candidato per una variabile.
    • Parker, tranne quando non lo sono (TRUE/FALSE)
    • Solo perché un numero magico non cambierà mai, non significa che non dovrebbe essere sostituito da una costante. Il mio codice è pieno di costanti globali come HzPerMHz e msecPerSecond. Questi non cambierà mai, ma il significato più chiaro, e di fornire protezione contro gli errori di battitura.
    • checkstyle può fare lo stesso in java.
    • Non sono d’accordo, dipende dal contesto.
    • altre buone naturale costanti includono ONE_MINUTE = 60, ONE_HOUR = 3600, ONE_DAY = 86400 (la maggior parte dei programmatori lavoreranno con epoch times)… o
    • che cosa si intende per “0 e 1 sono eccezioni a questa regola” ?
    • Direi che quel codice è MENO leggibile, perché voglio andare a caccia per la definizione di MAX_PASSWORD_SIZE quando non cambierà? si sta letteralmente solo fare più spaghettish.
    • Non sempre essere TRUE / FALSE come eccezione. Esempio: if(array.length == 0) (o < 1)
    • Non si poteva essere più sbagliato. Questa non è una questione di opinione, ma di duro guadagnato esperienza, da molti programmatori. Non posso dirvi quante volte, negli ultimi 40 anni di programmazione, che io ho maledetto un precedente programmatore che non si definisce una costante, così l’ho scoperto solo l’utilizzo diretto di un numero, che ha bisogno di essere capito, durante la manutenzione del codice, sepolto da qualche parte in un sacco di codice, il cui significato sarebbe stata chiara definizione di tale costante. Qualsiasi altro programmatore senior anche di più storie dell’orrore su questa linea.
    • … È fondamentale per ottenere l’abitudine di definire costanti per dare un senso al contrario di “arbitrario” numeri”, anche in banale metodi, in cui mi sembra ovvio. Perché? Perché, in futuro, tale metodo può ottenere aggiunto. Ciò che a prima vista sembrava ovvio, ora è da qualche parte all’interno di molte righe di codice. Per essere spaghettish, per quanto ne so tutte decente moderni Ide renderlo banale per trovare il valore di una costante variabile. Di solito è sufficiente passare il mouse su qualsiasi utilizzo della variabile. E anche indietro nel giorno, quando non ci sono tali sottigliezze, è stato molto, molto vale la pena nel lungo periodo.
    • Che dire cose come: connection.setTimeout(50); Dovrebbe 50 essere una costante qui? Sembra di essere abbastanza chiaro, che 50 è un timeout di connessione
    • 0, 1, -1 e 2 non sono considerati numeri di magia.
    • Perché sono 0,1,-1 e 2 Non sono considerati numeri di magia. Si può, si prega di condividere un punto di riferimento per questo? Sarebbe un aiuto.
    • MagicNumber : per impostazione predefinita, -1, 0, 1, e 2 non sono considerati numeri di magia. Riferimento
    • Tutto il bene e bene, ma la cosa è, quando si utilizza criteri di sospensione.elenco() ti capita spesso di avere un array di Oggetti e quindi non posso utilizzare una costante per indicare la posizione di indice del record di campo… 😛
    • su cose come: connessione.setTimeout(50); in caso di 50 essere una costante qui? Sembra di essere abbastanza chiaro, che il 50 è un timeout di connessione” – È un numero magico, indipendentemente di un singolo o più chiamata. Perché 50? Perché non 51? Potrebbe essere necessario cambiare, perché la distribuzione di un ambiente che richiede diversi timeout. Mi piacerebbe molto cambiare una costante di caccia attraverso il codice.
    • Hmm, appena imbattuto in questo, mentre l’attuazione di un hashCode() dove è frequente l’numeri di magia non utilizzato altrove. Ora lanugine mi impone di aggiungere una costante che IMHO non migliora la leggibilità di tutti. lint è giusto il 99% del tempo ant 1% del tempo è davvero sux.
    • Utilizza la magia dei numeri, è non è un male in sé. Un sacco di formule matematiche consistono in numeri di magia, davvero, molto. La stessa matematica, dove i computer e il software sono di costruire. È solo più utile fare riferimento al numero di che potrebbe essere rivisto in futuro una variabile. Quindi questa risposta è troppo semplicistico mio parere. Per l’implementazione di una semplice fisica in questo modo, si sa che cosa voglio dire.
    • è comunque possibile utilizzare una costante c’è nessun svantaggio IMHO, perché se si crea una “definizione di classe” per questo che proprio non contengono solo le costanti si avrà solo bisogno di andare lì cambia, invece di dare la caccia a tutti i punti con la stessa stringa. Inoltre, si potrebbe catena con String.Format() (C#) o che cosa mai si potrebbe fare public const string CELLPosition= "ROW{0}Col{1}" e quindi semplicemente String.Format(CELLPosition,row,col) e si ottiene ciò che si desidera.
    • Che dire di questo caso particolare? const passwordExpiresAt = moment().add(2, 'days').toDate(); Ho davvero bisogno di qualche costante PASSWORD_EXPIRE_TIME_IN_DAYS definito? Questo è solo uno spot nel codice, e il 2 significato è chiaramente raccolti dal resto della linea. Se ho successivamente modificata per 1 o 3, il significato è ancora evidente.
    • 1 e 0 può ancora essere di numeri di magia, semplicemente dipende dal contesto. Controllo if someArray.length === 0 lo scopo è ovvio, si sta verificando se è vuoto, non è considerato un numero magico. Ma poi se si createSomething(1), che è un numero magico. Non c’è modo di ottenere dal contesto, cosa che 1 è di circa – in particolare quando la 1 agisce come un boolean. Se hai avuto un true o false, è chiaro che questo parametro è attivato o disattivato.
    • Per me è un numero magico solo se il suo significato non è esplicito. Non capisco perché ti sembra di non essere se stessi chiedendo esattamente la stessa domanda (“perché il 50 e non 51”) se il numero è stato definito come una costante. Come per il futuro la richiesta di modifica, direi YAGNI (ma il giorno si ha bisogno di esso, sì da tutti i mezzi, il refactoring di un costante).
    • non ha nulla a che fare con il “significato”, esplicito o altro. Ha a che fare con valori hardcoded nel codice. Se lo stesso valore viene utilizzato più di una volta nel codice dovrebbe essere defined as a constant 1) per essere sicuri che il codice è in sync 2) in caso si desidera modificare facilmente nel future che un buon sviluppatore dovrebbe essere sempre a pensare. YAGNI, essendo un fautore del undisiplined lets-solo-ship-it-out-the-porta, che va contro il pensiero a lungo termine. Quindi non mi sorprende YAGNIs stanno facendo
    • Beh, secondo la definizione di Wikipedia (che mi pare una abbastanza decente di origine), è chiaro che parla di “inspiegabile senso”… E sicuramente mi ha fatto dire che si dovrebbe utilizzare costanti quando il valore è utilizzato in più punti, che è solo buon senso. Il mio punto è che, come per tutto nella zona di programmazione, è necessario essere pragmatici su di esso. C’è una differenza enorme tra password.length() > 7, che non è auto-esplicativo, e connection.setTimeout(50) in cui l’intenzione è del tutto chiaro.
    • Come per il YAGNI linea di principio, confermo tutto, in timeout caso, semplicemente perché “refactoring” è una costante, se necessario, non potrebbe essere più facile e veloce da fare. Io capisco la necessità di “pensiero a Lungo termine” quando speeking su una regola di business (come una lunghezza minima password) o di un’architettura di confine, ma qui, è solo un puro parametro tecnico.
    • Wow, appena imbattuto in questo, in modo da ri – uno dei primi commenti: HUNDRED_PERCENT potrebbe facilmente essere un valore costante! per una percentuale con precisione di 1/100 (0.01%-99.99%), è possibile utilizzare un HUNDRED_PERCENT=10000. Se hai sempre usato quel costante durante la conversione da decimale, funziona alla grande.
    • Ho trovato e costante magica in Integer.class if (radix == 10) { return toString(i); }

  2. 142

    Un Numero Magico è hardcoded di un valore che può cambiare in una fase successiva, ma che può essere quindi difficile da aggiornare.

    Per esempio, supponiamo di avere una Pagina che visualizza gli ultimi 50 Ordini in “i Tuoi Ordini” della Pagina di Riepilogo. 50 è il Numero Magico qui, perché non standard o convenzione, è un numero che è fatto per i motivi descritti nella specifica.

    Ora, quello che devi fare è di avere il 50 in luoghi diversi – il tuo script SQL (SELECT TOP 50 * FROM orders), il tuo Sito web (le Ultime 50 Ordini), l’ordine di accesso (for (i = 0; i < 50; i++)) e probabilmente molti altri luoghi.

    Ora, cosa succede quando qualcuno decide di cambiare 50 a 25? o 75? o 153? È ora di sostituire il 50 in tutti i luoghi, ed è molto probabile che a perdere. Trova/Sostituisci non può funzionare, perché 50 può essere utilizzato per altre cose, e ciecamente sostituzione di 50 con 25 può avere altri effetti collaterali negativi (cioè il vostro Session.Timeout = 50 chiamata, che è anche il set per 25 utenti e avviare la creazione di report troppo frequenti timeout).

    Inoltre, il codice può essere difficile da capire, cioè “if a < 50 then bla” – se si verifica che, nel mezzo di una complicata funzione, altri sviluppatori che non hanno familiarità con il codice potrebbe chiedersi: “WTF è di 50???”

    Ecco perché è meglio avere tale ambiguo e numeri arbitrari esattamente 1 posto – “const int NumOrdersToDisplay = 50“, perché rende il codice più leggibile (“if a < NumOrdersToDisplay“, significa, inoltre, è solo bisogno di cambiare in 1 ben definito luogo.

    Luoghi dove i Numeri Magici sono appropriato è tutto ciò che è definito uno standard, cioè SmtpClient.DefaultPort = 25 o TCPPacketSize = whatever (non so se è standardizzato). Inoltre, tutto solo definito entro 1 funzione potrebbe essere accettabile, ma che dipende dal Contesto.

    • Anche se non può cambiare è ancora una cattiva idea, anche perché non è chiaro cosa sta succedendo.
    • Non è sempre chiaro. SmtpClient.DefaultPort = 25 è forse chiaroer di SmtpClient.DefaultPort = DEFAULT_SMTP_PORT.
    • Suppongo che è supponendo che non c’è assolutamente nessun altro codice che utilizza il concetto di DEFAULT_SMTP_PORT. Se il valore predefinito della porta SMTP per l’applicazione è cambiato, allora si avrebbe bisogno di essere aggiornato in più punti provocando la possibilità di incoerenza.
    • È anche più difficile trovare tutti gli usi – dovresti cercare 25 in tutta l’applicazione e assicurarsi che si modifica solo le occorrenze di 25 che sono per la Porta SMTP, non il 25 che sono, per esempio, la larghezza di una colonna di una tabella o il numero di record da visualizzare in una pagina.
    • In questo esempio, mi aspetto il codice per utilizzare SmtpClient.DefaultPort, non 25. Quindi bisogna cambiare in un unico luogo. E il numero di porta è probabile che rimanga la stessa, non è un casuale numero magico, ma un numero assegnato dal IANA.
  3. 32

    Hai dato un’occhiata alla voce di Wikipedia per numero magico?

    Va in un po ‘ di dettaglio su tutti i modi in cui il numero magico è fatto riferimento. Qui una citazione su ” numero magico, come una cattiva pratica di programmazione

    Il termine “numero magico” si riferisce anche alla cattiva pratica di programmazione di utilizzare i numeri direttamente nel codice sorgente, senza spiegazione. Nella maggior parte dei casi questo rende i programmi più difficile da leggere, capire e gestire. Sebbene la maggior parte delle guide di fare un’eccezione per i numeri zero e uno, è una buona idea per definire tutti gli altri numeri in codice denominato costanti.

    • Buon esempio di RTFW 🙂
    • Direi che la risposta è tutt’altro che pieno.
  4. 23

    Numero Magico Vs. Costante simbolica: Quando sostituire?

    Magia: Unknown semantica

    Costante simbolica -> Fornisce sia corretta semantica e contesto corretto per utilizzare

    Semantica: Il significato o lo scopo di una cosa.

    “Creare una costante, il nome, il significato, e sostituire il numero con esso.” — Martin Fowler

    Primo, numeri di magia non sono solo numeri. Qualsiasi valore di base può essere la “magia”. I valori di base sono manifesto di enti come numeri interi, reali, doppie, galleggianti, date, stringhe, booleani, caratteri, e così via. Il problema non è il tipo di dati, ma la “magia” aspetto di valore come appare nel nostro codice di testo.

    Cosa si intende per “magia”? Per essere precisi: Da “magia”, si intende per scegliere la semantica (significato o scopo) di valore nel contesto del nostro codice; che è ignoto, l’inconoscibile, poco chiare o confuse. Questa è la nozione di “magia”. Un valore di base non è magia, quando il suo significato semantico, o come scopo, di essere facilmente e rapidamente noto, chiaro e comprensibile (non confondere) dal surround contesto senza l’aiuto speciale di parole (ad esempio, costante simbolica).

    Pertanto, siamo in grado di identificare numeri di magia, misura la capacità di un lettore di codice a sapere, essere chiaro, e di comprendere il senso e lo scopo di un valore di base dal contesto circostante. Il meno conosciuto, meno chiaro e più confuso il lettore è, il più “magico” il valore di base è.

    Definizioni Utili

    • confondere: causa (qualcuno) per diventare disorientato o perplesso.
    • sconcertato: causa (qualcuno) per diventare perplesso e confuso.
    • perplesso: completamente perplesso, molto perplesso.
    • sconcertati: totalmente strano o perplesso.
    • perplesso: non in grado di capire; perplesso.
    • capire: percepire il significato (parole, una lingua, o altoparlante).
    • significato: il significato di una parola, testo, concetto, o azione.
    • dire: intende trasmettere, indicare, o fare riferimento a una particolare cosa o concetto); significano.
    • significare: essere un’indicazione di.
    • indicazione: a segno o un pezzo di informazioni che indica qualcosa.
    • indicare: indicare, mostrare.
    • segno: un oggetto, di qualità, o di un evento la cui presenza o la comparsa indica la probabile presenza o la comparsa di qualcosa d’altro.

    Basi

    Abbiamo due scenari per la magia dei nostri valori fondamentali. Solo il secondo è di primaria importanza per i programmatori e codice:

    1. Un solo valore di base (ad es. numero) da cui il suo significato è ignoto, l’inconoscibile, poco chiare o confuse.
    2. Un valore di base (ad es. numero) in un contesto, ma il significato rimane ignoto, l’inconoscibile, poco chiare o confuse.

    Generale dipendenza di “magia” è come il lone valore di base (ad es. numero) non ha conosciuto comunemente semantica (come Pi), ma è un locale conosciuto semantica (ad esempio, un programma), che non è del tutto chiaro dal contesto o potrebbe essere abusato di una buona o una cattiva contesto(s).

    La semantica dei linguaggi di programmazione non ci permetterà di utilizzare lone valori di base, tranne (forse) come dati (ad es. tabelle di dati). Quando ci imbattiamo in “magic numbers”, generalmente si fanno in un contesto. Pertanto, la risposta alla

    “Posso sostituire questo numero magico con una costante simbolica?”

    è:

    “Quanto velocemente si può valutare e comprendere il significato semantico del
    numero (il suo scopo per essere lì) nel suo contesto?”

    Tipo di Magia, ma non abbastanza

    Con questo pensiero in mente, siamo in grado di vedere rapidamente come un numero, come Pi (3.14159) non è un “numero magico”, quando sono immessi in un contesto appropriato (ad esempio, 2 x 3.14159 raggio x o 2*Pi*r). Qui, il numero di 3,14159 è mentalmente riconosciuto Pi senza la costante simbolica identificatore.

    Ancora, generalmente sostituire 3.14159 con una costante simbolica identificatore come Pi a causa della lunghezza e della complessità del numero. Gli aspetti di lunghezza e la complessità del Pi (accoppiato con un bisogno per la precisione), di solito significa l’identificatore simbolico o costante è meno soggetta a errori. Il riconoscimento di “Pi” come un nome, è semplicemente una comoda bonus, ma non è il motivo principale per avere la costante.

    Nel frattempo: Torna al Ranch

    Mettere da parte le costanti comuni come il Pi, ci concentreremo principalmente sui numeri con significati particolari, ma che questi significati sono vincolati all’universo del nostro software di sistema. Tale numero potrebbe essere “2” (come fondamentale valore intero).

    Se posso utilizzare il numero 2 di per sé, la mia prima domanda potrebbe essere: che Cosa significa “2” significa? Il significato di “2” di per sé è sconosciuto e inconoscibile, senza contesto, lasciando il suo uso poco chiaro e confuso. Anche se avendo appena “2” nel nostro software non accadrà a causa della lingua semantica, noi vogliamo vedere che il “2” di per sé non comporta alcun semantica o evidente scopo di essere da solo.

    Mettiamo il nostro unico “2” in un contesto di: padding := 2, dove il contesto è una “GUI Contenitore”. In questo contesto, il significato di 2 (come pixel o altre unità grafiche) ci offre un rapido indovinare la sua semantica (significato e di scopo). Potremmo fermarci qui e dire che 2 è ok, in questo contesto, e non c’è altro che dobbiamo sapere. Tuttavia, forse il nostro software universo questa non è tutta la storia. C’è di più, ma “padding = 2” in un contesto che non può rivelare.

    Facciamo un ulteriore fingere di 2 pixel di padding nel nostro programma è di “default_padding” varietà in tutto il nostro sistema. Pertanto, la scrittura di istruzione padding = 2 non è abbastanza buono. La nozione di “default” non è rivelato. Solo quando scrivo: padding = default_padding come contesto, e poi altrove: default_padding = 2 faccio pienamente realizzare un migliore e più pieno significato (semantica e di scopo) di 2 nel nostro sistema.

    Esempio di cui sopra è abbastanza buona perché “2” potrebbe essere qualsiasi cosa. Solo quando ci limitare la gamma di dominio e di comprensione “il mio programma” dove 2 è il default_padding nella GUI UX parti di “il mio programma”, possiamo finalmente dare un senso a “2” nel suo giusto contesto. Qui il “2” è una “magia”, il numero che si somma a una costante simbolica default_padding nel contesto della GUI UX di “il mio programma”, per farne uso come default_padding rapidamente inteso nel più ampio contesto della allegando il codice.

    Pertanto, qualsiasi valore di base, il cui significato (semantica e di scopo) non possono essere sufficientemente e rapidamente capito che è un buon candidato per una costante simbolica in luogo del valore di base (ad es. numero magico).

    Di Andare Avanti

    Numeri su una scala potrebbe avere semantica così. Per esempio, far finta che stiamo facendo, D&D di gioco, dove abbiamo l’idea di un mostro. Il nostro mostro oggetto ha una funzione chiamata life_force, che è un numero intero. I numeri hanno un significato che non è conoscibile o cancellare senza parole per la fornitura di significato. Dunque, cominciamo da arbitrariamente dicendo:

    • full_life_force: INTEGER = 10 — Molto vivo (e non)
    • minimum_life_force: INTEGER = 1 — a Malapena (molto male)
    • morti: INTEGER = 0 — Morto
    • non morti: INTEGER = -1 — Min non morti (quasi morto)
    • zombie: INTEGER = -10 — Max non morti (molto undead)

    Dal costanti simboliche di cui sopra, si inizia ad avere un immagine mentale di vitalità, morta, e “undeadness” (e le possibili implicazioni o conseguenze) per i nostri mostri in D&D di gioco. Senza queste parole (costanti simboliche), si sono lasciati con solo i numeri che vanno da -10 .. 10. Solo l’intervallo senza le parole ci lascia in un luogo possibilmente in una grande confusione e, potenzialmente, con errori nel nostro gioco, se in diverse parti del gioco sono le dipendenze, su cosa intervallo di numeri significa varie operazioni come attack_elves o seek_magic_healing_potion.

    Pertanto, quando si cerca e considerando la sostituzione dei “numeri magici” vogliamo chiedere a scopo pieni di domande circa i numeri nel contesto del nostro software e anche come i numeri di interagire dal punto di vista semantico con l’altro.

    Conclusione

    Esaminiamo quali domande si dovrebbe chiedere:

    Si potrebbe avere un numero magico … se

    1. Possibile il valore di base hanno un particolare significato o scopo nel vostro software universo?
    2. Possibile il particolare significato o scopo probabilmente ignoto, l’inconoscibile, poco chiare o confuse, anche nel suo giusto contesto?
    3. Possibile un corretto valore di base, impropriamente utilizzato con conseguenze negative nel contesto sbagliato?
    4. Un improprio valore di base essere usati correttamente e con conseguenze negative nel contesto giusto?
    5. Il valore di base hanno una semantica, o come scopo, di relazioni con altri valori di base in contesti specifici?
    6. Possibile un valore di base esistono in più di un posto nel nostro codice con una semantica diversa in ogni, causando in tal modo al lettore di confusione?

    Esaminare stand-alone manifesto costante i valori di base nel vostro testo del codice. Chiedi a ogni domanda lentamente e accuratamente su ogni istanza di tale valore. Considerare la forza della tua risposta. Molte volte, la risposta non è in bianco e nero, ma ha sfumature frainteso il significato e lo scopo, velocità di apprendimento, e la velocità di comprensione. C’è anche bisogno di vedere come si collega al software della macchina intorno ad esso.

    Alla fine, la risposta per la sostituzione è di rispondere a misura (nella tua mente) la forza o la debolezza del lettore per effettuare la connessione (ad esempio, “get”). Il più rapidamente capiscono il significato e lo scopo, il meno “magia” che si hanno.

    CONCLUSIONE: Sostituire i valori di base con costanti simboliche solo quando la magia è grande abbastanza per provocare difficile rilevare i bug derivanti da confusioni.

  5. 18

    Un numero magico è una sequenza di caratteri all’inizio di un formato di file o un protocollo di scambio. Questo numero serve come un controllo di integrità.

    Esempio:
    Aprire qualsiasi file GIF, si vedrà all’inizio: GIF89. “GIF89” essere il numero magico.

    Altri programmi in grado di leggere i primi caratteri di un file e di identificare correttamente le Gif.

    Il pericolo è che casuale di dati binari possono contenere questi stessi personaggi. Ma è molto improbabile.

    Come per il protocollo di exchange, è possibile utilizzare per identificare rapidamente che l’attuale “messaggio” che viene passato è danneggiato o non valido.

    I numeri magici sono ancora utili.

    • Non credo che il numero magico era riferito a
    • Forse si dovrebbe rimuovere il “formato file” e “networking” tag aggiunti perché chiaramente non si parla di questi tipi di numeri di magia.
    • È ancora molto utile sapere che i numeri di magia può fare riferimento a più di un semplice codice di problema. -Adam
    • Se il soggetto leggere: “che Cosa è un numero magico in termini di codice sorgente”, quindi il tag non dovrebbe essere lì. Ma lui non lo specifica. In modo da avere il mio extra informazione è un bene. Penso Kyle, Landon e Marcio sono sbagliato.
    • Non c’era alcun modo per determinare che quello che stava cercando. Dato che sono stato il primo post che ho potuto intuire che quello che stava cercando.
  6. 11

    Nella programmazione, un “numero magico” è un valore che deve essere dato un nome simbolico, ma è invece scivolato in il codice come un letterale, di solito in più di un posto.

    È un male per lo stesso motivo SPOT (Punto Unico di Verità) è un bene: Se si vuole cambiare questa costante più tardi, si sarebbe dovuto cercare con il vostro codice di trovare ogni istanza. È anche un male, perché potrebbe non essere chiaro per altri programmatori che questo numero rappresenta, quindi, la “magia”.

    Gente, a volte, prendere il numero magico eliminazione ulteriormente, spostando queste costanti, in un file separato di agire come configurazione. Questo a volte è utile, ma può anche creare una complessità maggiore di quanto ne vale la pena.

    • Puoi essere più specifico sul perché eliminando maginc numeri NON È sempre buona?
    • In formule matematiche come e^pi + 1 = 0
    • Penso che voleva dire che non è sempre buona per passare di numeri di magia per i file di configurazione, che condivido.
    • Marcio: Quando si fanno le cose come “const int OTTO = 8;” e poi cambiano i requisiti e si finisce con “const int OTTO = 9;”
    • Mi dispiace, ma questo è semplicemente un esempio di cattiva denominazione, o una base di utilizzo costante.
    • Su alcune piattaforme, un’espressione come (foo[i]+foo[i+1]+foo[i+2]+1)/3 può essere valutata molto più veloce di un ciclo. Se si dovesse sostituire il 3 senza dover riscrivere il codice come un ciclo, qualcuno che ha visto ITEMS_TO_AVERAGE definito come 3 potrebbero figura potrebbe cambiare per 5 e il codice media più elementi. Al contrario, qualcuno che guardava l’espressione letterale 3 renderebbe conto che la 3 rappresenta il numero di elementi sommati insieme.
    • Come circa quadratic_root = (-b + sqrt(b*b - 4*a*c)) / (2*a)? Davvero qualsiasi formula matematica in cui i “numeri magici” non hanno un significato al di là della loro inclusione nella formula.

  7. 10

    Un problema che non è stato menzionato con l’utilizzo di numeri di magia…

    Se si dispone di molti di loro, le probabilità sono abbastanza buone che si dispone di due diversi fini che si sta utilizzando numeri di magia, dove la valori capita di essere lo stesso.

    E poi, certo, basta, è necessario modificare il valore… per un solo scopo.

    • Questo non sembra del tutto probabile che quando si parla di numeri (almeno non per me), ma mi sono imbattuto in esso con stringhe ed è un successo: prima devi leggere un sacco di codice per vedere dove il suo utilizzo, rispetto a notare che è stato utilizzato per diverse cose…non è il mio passatempo preferito.
  8. 9

    Un numero magico può anche essere un numero speciale, hardcoded semantica. Per esempio, una volta ho visto un sistema in cui gli Id record > 0 sono stati trattati normalmente, 0 sé era “nuovo record”, -1 è stato “questa è la radice” e -99 è stata “questo è stato creato nella root”. 0 e -99 causerebbe il WebService per la fornitura di un nuovo ID.

    Cosa brutta di questo è che si sta riutilizzo di uno spazio (che firma interi record Id) per le abilità speciali. Forse non avrai mai voglia di creare un record con ID 0, o con un ID negativo, ma anche se non, ogni persona che guarda sia al codice o al database potrebbe inciampare su questo e essere confuso in un primo momento. Va da sé quei valori non erano ben documentato.

    Probabilmente, 22, 7, -12 e 620 contano come numeri di magia, troppo. 😉

  9. 4

    Presumo questa è una risposta al mio risposta alla tua domanda precedente. In programmazione, un numero magico è un integrato costante numerica che appare senza spiegazione. Se appare in due località distinte, può portare a casi in cui un esempio è cambiato e non in un altro. Per entrambe queste ragioni, è importante isolare e definire le costanti numeriche fuori dai luoghi in cui sono utilizzati.

  10. 3

    Vale la pena di notare che, a volte, si desidera non è configurabile “hard-coded” numeri in codice. Ci sono un certo numero di quelli famosi tra 0x5F3759DF che viene utilizzato nel ottimizzato inverso del quadrato della radice algoritmo.

    Nei rari casi In cui ho bisogno di utilizzare questi Numeri Magici, ho impostato come un const nel mio codice, e documento perché essi vengono utilizzati, come funzionano, e da dove sono venuti.

    • A mio parere, il numero magico codice odore si riferisce specificamente a inspiegabile costanti. Finché si sta mettendo in un costante, non dovrebbe essere un problema.
  11. 3

    Ho sempre usato il termine “numero magico” in modo diverso, come un oscuro valore memorizzato all’interno di una struttura di dati che può essere verificato come un rapido controllo di validità. Per esempio gzip file contengono 0x1f8b08 come i loro primi tre byte, i file di classe Java iniziare con 0xcafebabe, etc.

    Si vedono spesso di numeri di magia incorporato in formati di file, perché i file possono essere inviati in giro piuttosto promiscuamente e perdere tutti i dati su come sono stati creati. Tuttavia i numeri magici sono anche talvolta utilizzato per strutture di dati in memoria, come ioctl() chiama.

    Un rapido controllo del numero magico prima di elaborare il file o la struttura di dati permette di errori di segnale precoce, piuttosto che fatica tutto il percorso attraverso potenzialmente di lunga durata trattamento, per annunciare che l’ingresso era completa balderdash.

  12. 3

    Che cosa circa l’inizializzazione di una variabile al top della sua classe con un valore di default? Per esempio:

    public class SomeClass {
        private int maxRows = 15000;
        ...
        //Inside another method
        for (int i = 0; i < maxRows; i++) {
            //Do something
        }
    
        public void setMaxRows(int maxRows) {
            this.maxRows = maxRows;
        }
    
        public int getMaxRows() {
            return this.maxRows;
        }
    

    In questo caso, 15000 è un numero magico (secondo CheckStyles). Per me, l’impostazione di un valore di default è ok. Non voglio avere a che fare:

    private static final int DEFAULT_MAX_ROWS = 15000;
    private int maxRows = DEFAULT_MAX_ROWS;
    

    Fa che rendere più difficile la lettura? Non ho mai considerato questo fino a quando ho installato CheckStyles.

    • Credo che questo sarebbe bene se il costruttore inizializza il valore. Altrimenti, se il valore è inizializzato al di fuori del costruttore, ho appena vedono come un fastidio e, come qualcosa di più difficile lettura.
    • Penso static final costanti sono utilissime quando si sta utilizzando il loro metodo. Un final variabile dichiarata in cima il metodo è più leggibile IMHO.
  13. 1

    @eed3si9n: vorrei anche suggerire che ‘1 è un numero magico. 🙂

    Un principio, che è legato alla magia dei numeri è che ogni fatto che il codice si occupa devono essere dichiarati esattamente una volta. Se si usa la magia dei numeri in codice (ad esempio la lunghezza della password per l’esempio che @marcio ha dato, si può facilmente finire la duplicazione di questo fatto, e quando hai capito del fatto che modifiche hai un problema di manutenzione.

    • IOW codice dovrebbe essere scritto come: factorial n = if n == BASE_CASE then BASE_VALUE else n * factorial (n - RECURSION_INPUT_CHANGE); RECURSION_INPUT_CHANGE = 1; BASE_CASE = 0; BASE_VALUE = 1
  14. 1

    Quello di ritorno variabili?

    Particolare mi è difficile quando attuazione stored procedure.

    Immaginare il prossimo stored procedure (sintassi sbagliata, lo so, proprio per mostrare un esempio):

    int procGetIdCompanyByName(string companyName);
    

    Restituire l’Id della società, se esiste, di una particolare tabella. In caso contrario, restituisce -1.
    In qualche modo è un numero magico. Alcuni dei consigli che ho letto finora, dice che mi hanno veramente a fare la progettazione di qualcosa di simile a questo:

    int procGetIdCompanyByName(string companyName, bool existsCompany);
    

    A proposito, che cosa dovrebbe restituire se la società non esiste? Ok: per impostare existesCompany come false, ma anche di restituire -1.

    Altro opzione è quella di fare due distinte funzioni:

    bool procCompanyExists(string companyName);
    int procGetIdCompanyByName(string companyName);
    

    Quindi, una pre-condizione per la seconda stored procedure è la società che esiste.

    Ma ho paura della concorrenza, perché in questo sistema, una società può essere creato da un altro utente.

    La linea di fondo è: cosa pensate dell’utilizzo di quel tipo di “numeri magici” che sono relativamente noti e sicuro per dire che qualcosa è successo o che qualcosa non esiste?

    • In questo caso specifico, se la documentazione della funzione afferma che un ipotetico valore significa che l’impresa non è stato trovato, quindi non c’è alcun motivo per l’utilizzo di una costante.
  15. 0

    Un altro vantaggio di estrarre un numero magico, come una costante, dà la possibilità di documentare in modo chiaro le informazioni di business.

    public class Foo {
        /** 
         * Max age in year to get child rate for airline tickets
         * 
         * The value of the constant is {@value}
         */
        public static final int MAX_AGE_FOR_CHILD_RATE = 2;
    
        public void computeRate() {
             if (person.getAge() < MAX_AGE_FOR_CHILD_RATE) {
                   applyChildRate();
             }
        }
    }
    

Lascia un commento