Cos'è un numero magico e perché è cattivo? [chiuso]


514

Cos'è un numero magico?

Perché dovrebbe essere evitato?

Ci sono casi in cui è appropriato?


2
Eviteresti numeri magici perché altre persone che visualizzano il tuo codice potrebbero non capire perché stai facendo quello che stai facendo ... ad esempio in const myNum = 22; const number = myNum / 11;questo momento i miei 11 potrebbero essere persone o bottiglie di birra o qualcosa del genere, quindi invece cambierei 11 in una costante come gli abitanti.
JuicY_Burrito,

L'uso dei numeri magici negli attributi è inevitabile, quindi immagino che sia appropriato.
donatasj87,

Risposte:


575

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

Ad esempio, se hai (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 refactored per:

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. Immagina il caso in cui ho impostato la dimensione del campo password nella GUI. Se uso un numero magico, ogni volta che cambia la dimensione massima, devo cambiare in due posizioni di codice. Se ne dimentico uno, questo porterà a incoerenze.

Il JDK è piena di esempi come in Integer, Charactere Mathle classi.

PS: strumenti di analisi statica come FindBugs e PMD rilevano l'uso di numeri magici nel tuo codice e suggeriscono il refactoring.


175
0 e 1 sono eccezioni a questa regola.
Jonathan Parker,

24
@Kirill: se ti aspetti che la definizione di "Cento percentuali" cambi, allora sì. Un approccio migliore sarebbe quello di avere la variabile da ciò che è a ciò che rappresenta, vale a dire, finale statico pubblico MAX_DOWNLOAD_PERCENTAGE = 100. Anche se anche questo non avrebbe senso, perché "100 percento" è molto ben definito. D'altra parte, il fatto che le password possano avere una lunghezza massima di 7 caratteri non è definito a livello globale e in realtà differisce, quindi è candidato per una variabile.
Michael Stum

40
@Jonathan Parker, tranne quando non lo sono ( TRUE/ FALSE)
Brendan Long

82
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 cambieranno mai, ma rendono il significato più chiaro e forniscono una certa protezione contro i refusi.
Jeanne Pindar,

43
@MarcusJ Non potresti sbagliare di più. Questa non è una questione di opinione, ma di esperienza maturata duramente, da molti programmatori. Non posso dirti quante volte, negli ultimi 40 anni di programmazione, ho maledetto un programmatore precedente che non aveva definito una costante, quindi ho scoperto solo l'uso diretto di un numero, che doveva essere compreso durante la manutenzione del codice , sepolto da qualche parte in un sacco di codice, il cui significato sarebbe stato chiarito definendo una tale costante. Allo stesso modo, qualsiasi altro programmatore senior avrà più storie dell'orrore su questa linea.
ToolmakerSteve

146

Un numero magico è un valore codificato che può cambiare in un secondo momento, ma che può quindi essere difficile da aggiornare.

Ad esempio, supponiamo che tu abbia una Pagina che mostra gli ultimi 50 ordini in una pagina di riepilogo "I tuoi ordini". 50 è il numero magico qui, perché non è impostato tramite standard o convenzione, è un numero che hai inventato per i motivi indicati nelle specifiche.

Ora, quello che fai è che hai i 50 in luoghi diversi: il tuo script SQL ( SELECT TOP 50 * FROM orders), il tuo sito Web (i tuoi ultimi 50 ordini), il tuo login dell'ordine ( for (i = 0; i < 50; i++)) e possibilmente molti altri luoghi.

Ora, cosa succede quando qualcuno decide di cambiare da 50 a 25? o 75? o 153? Ora devi sostituire il 50 in tutti i posti e molto probabilmente ti mancherà. Trova / Sostituisci potrebbe non funzionare, perché 50 potrebbe essere utilizzato per altre cose e la sostituzione alla cieca di 50 con 25 può avere altri effetti collaterali negativi (ad esempio, la tua Session.Timeout = 50chiamata, che è anche impostata su 25 e gli utenti iniziano a segnalare timeout troppo frequenti).

Inoltre, il codice può essere difficile da capire, ad esempio " if a < 50 then bla" - se lo si incontra nel mezzo di una funzione complicata, altri sviluppatori che non hanno familiarità con il codice potrebbero chiedersi "WTF è 50 ???"

Ecco perché è meglio avere numeri così ambigui e arbitrari in esattamente 1 posto - " const int NumOrdersToDisplay = 50", perché ciò rende il codice più leggibile (" if a < NumOrdersToDisplay", significa anche che devi solo cambiarlo in 1 posto ben definito.

I luoghi in cui i numeri magici sono appropriati è tutto ciò che è definito attraverso uno standard, ovvero SmtpClient.DefaultPort = 25o TCPPacketSize = whatever(non sono sicuro che sia standardizzato). Inoltre, tutto ciò che è definito solo all'interno di 1 funzione potrebbe essere accettabile, ma ciò dipende dal contesto.


18
Anche se non può cambiare, è comunque una cattiva idea perché non è chiaro cosa stia succedendo.
Loren Pechtel,

11
Non è sempre poco chiaro. SmtpClient.DefaultPort = 25è forse chiaro er rispetto SmtpClient.DefaultPort = DEFAULT_SMTP_PORT.
user253751

4
@immibis Suppongo che stia supponendo che non ci sia assolutamente nessun altro codice che usi il concetto di DEFAULT_SMTP_PORT. Se la porta SMTP predefinita per quell'applicazione viene modificata, dovrebbe essere aggiornata in più punti causando la possibilità di incoerenza.
Russ Bradberry,

3
È anche più difficile trovare tutti gli usi: dovresti cercare in 25tutta l'applicazione e assicurarti di modificare solo le occorrenze di 25quelle per la porta SMTP, non i 25 che sono ad esempio la larghezza di una colonna della tabella o il numero di record da mostrare in una pagina.
Michael Stum

2
In questo esempio, mi aspetto che il codice utilizzi SmtpClient.DefaultPort, non 25. Quindi dovresti semplicemente cambiarlo in un posto. E è probabile che il numero di porta rimanga lo stesso, non è un numero magico casuale, ma un numero assegnato da IANA.
njsg,

34

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

Descrive in dettaglio tutti i modi in cui viene fatto il riferimento al numero magico. Ecco una citazione sul numero magico come una cattiva pratica di programmazione

Il termine numero magico si riferisce anche alla cattiva pratica di programmazione dell'utilizzo dei numeri direttamente nel codice sorgente senza spiegazione. Nella maggior parte dei casi ciò rende i programmi più difficili da leggere, comprendere e mantenere. Sebbene la maggior parte delle guide faccia un'eccezione per i numeri zero e uno, è una buona idea definire tutti gli altri numeri nel codice come costanti nominate.


8
Un buon esempio di RTFW :)
Eva

Direi che la risposta è tutt'altro che completa.
Skeeve

25

Numero magico vs. Costante simbolica: quando sostituirla?

Magia: semantico sconosciuto

Costante simbolica -> Fornisce sia il contesto semantico che quello corretto per l'uso

Semantico: il significato o lo scopo di una cosa.

"Crea una costante, chiamala in base al significato e sostituisci il numero con essa." - Martin Fowler

Innanzitutto, i numeri magici non sono solo numeri. Qualsiasi valore di base può essere "magico". I valori di base sono entità manifest come numeri interi, reali, doppi, float, date, stringhe, valori booleani, caratteri e così via. Il problema non è il tipo di dati, ma l'aspetto "magico" del valore come appare nel nostro testo in codice.

Cosa intendiamo per "magia"? Per essere precisi: per "magia", intendiamo indicare la semantica (significato o scopo) del valore nel contesto del nostro codice; che è sconosciuto, inconoscibile, poco chiaro o confuso. Questa è la nozione di "magia". Un valore di base non è magico quando il suo significato semantico o lo scopo dell'essere è rapidamente e facilmente conosciuto, chiaro e compreso (non confuso) dal contesto surround senza parole speciali di supporto (ad esempio costante simbolica).

Pertanto, identifichiamo i numeri magici misurando la capacità di un lettore di codice di conoscere, essere chiaro e comprendere il significato e lo scopo di un valore di base dal suo contesto circostante. Meno noto, meno chiaro e più confuso è il lettore, più "magico" è il valore di base.

Definizioni utili

  • confondere: causare (qualcuno) sconcertato o perplesso.
  • sconcertato: causare (qualcuno) perplesso e confuso.
  • perplesso: completamente perplesso; molto perplesso.
  • sconcertato: totalmente perplesso o perplesso.
  • perplesso: incapace di capire; perplesso.
  • capire: percepire il significato previsto di (parole, una lingua o un oratore).
  • significato: cosa si intende per parola, testo, concetto o azione.
  • significava: intende trasmettere, indicare o riferirsi a (una cosa o nozione particolare); significare.
  • significa: essere un'indicazione di.
  • indicazione: un segno o un'informazione che indica qualcosa.
  • indicare: sottolineare; mostrare.
  • segno: un oggetto, una qualità o un evento la cui presenza o occorrenza indica la probabile presenza o occorrenza di qualcos'altro.

Nozioni di base

Abbiamo due scenari per i nostri magici valori di base. Solo il secondo è di primaria importanza per programmatori e codice:

  1. Un valore di base solitario (ad es. Numero) dal quale il suo significato è sconosciuto, inconoscibile, poco chiaro o confuso.
  2. Un valore di base (ad es. Numero) nel contesto, ma il suo significato rimane sconosciuto, inconoscibile, poco chiaro o confuso.

Una dipendenza generale della "magia" è come il valore di base solitario (ad esempio il numero) non abbia un semantico comunemente noto (come Pi), ma abbia un semantico conosciuto localmente (ad esempio il programma), che non è del tutto chiaro dal contesto o potrebbe essere abusato in contesti positivi o negativi.

La semantica della maggior parte dei linguaggi di programmazione non ci consentirà di utilizzare valori di base solitari, tranne (forse) come dati (ovvero tabelle di dati). Quando incontriamo "numeri magici", generalmente lo facciamo in un contesto. Pertanto, la risposta a

"Sostituisco questo numero magico con una costante simbolica?"

è:

"Quanto velocemente puoi valutare e comprendere il significato semantico del numero (il suo scopo di essere lì) nel suo contesto?"

Kind of Magic, ma non del tutto

Con questo pensiero in mente, possiamo rapidamente vedere come un numero come Pi (3.14159) non sia un "numero magico" se collocato nel contesto appropriato (ad esempio 2 x 3.14159 x raggio o 2 * Pi * r). Qui, il numero 3.14159 è mentalmente riconosciuto Pi senza l'identificatore simbolico costante.

Tuttavia, generalmente sostituiamo 3.14159 con un identificatore simbolico costante come Pi a causa della lunghezza e della complessità del numero. Gli aspetti di lunghezza e complessità di Pi (associati a una necessità di precisione) di solito indicano che l'identificatore simbolico o la costante sono meno inclini all'errore. Il riconoscimento di "Pi" come nome è semplicemente un vantaggio conveniente, ma non è il motivo principale per avere la costante.

Nel frattempo: ritorno al ranch

Mettendo da parte le costanti comuni come Pi, concentriamoci principalmente su numeri con significati speciali, ma che tali significati sono vincolati all'universo del nostro sistema software. Tale numero potrebbe essere "2" (come valore intero di base).

Se uso il numero 2 da solo, la mia prima domanda potrebbe essere: cosa significa "2"? Il significato di "2" di per sé è sconosciuto e inconoscibile senza contesto, lasciando il suo uso poco chiaro e confuso. Anche se avere solo "2" nel nostro software non accadrà a causa della semantica del linguaggio, vogliamo vedere che "2" da solo non ha una semantica speciale o uno scopo ovvio essendo solo.

Mettiamo il nostro solitario "2" in un contesto di:, padding := 2dove il contesto è un "contenitore GUI". In questo contesto il significato di 2 (come pixel o altra unità grafica) ci offre una rapida ipotesi della sua semantica (significato e scopo). Potremmo fermarci qui e dire che 2 va bene in questo contesto e non c'è nient'altro che dobbiamo sapere. Tuttavia, forse nel nostro universo software questa non è l'intera storia. C'è di più, ma "padding = 2" come contesto non può rivelarlo.

Supponiamo inoltre che 2 come pixel padding nel nostro programma sia della varietà "default_padding" in tutto il nostro sistema. Pertanto, scrivere le istruzioni padding = 2non è abbastanza buono. La nozione di "default" non viene rivelata. Solo quando scrivo: padding = default_paddingcome contesto e poi altrove: default_padding = 2realizzo pienamente un significato migliore e più pieno (semantico e scopo) di 2 nel nostro sistema.

L'esempio sopra è abbastanza buono perché "2" da solo potrebbe essere qualsiasi cosa. Solo quando limitiamo l'intervallo e il dominio della comprensione al "mio programma" in cui 2 è parte default_paddingdella "GUI UX" del "mio programma", possiamo finalmente dare un senso a "2" nel suo giusto contesto. Qui "2" è un numero "magico", che viene preso in considerazione in una costante simbolica default_paddingnel contesto della GUI UX del "mio programma" al fine di farne un uso il più default_paddingrapidamente compreso nel contesto più ampio del codice allegato.

Pertanto, qualsiasi valore di base, il cui significato (semantico e scopo) non può essere sufficientemente e rapidamente compreso, è un buon candidato per una costante simbolica al posto del valore di base (ad es. Numero magico).

Andare avanti

Anche i numeri su una scala possono avere semantica. Ad esempio, fingiamo di creare un gioco D&D, in cui abbiamo l'idea di un mostro. Il nostro oggetto mostro ha una funzione chiamata life_force, che è un numero intero. I numeri hanno significati che non sono conoscibili o chiari senza parole per fornire significato. Quindi, iniziamo dicendo arbitrariamente:

  • full_life_force: INTEGER = 10 - Molto vivo (e non danneggiato)
  • minimum_life_force: INTEGER = 1 - A malapena vivo (molto ferito)
  • morto: INTEGER = 0 - Morto
  • non morti: INTEGER = -1 - Min non morti (quasi morti)
  • zombie: INTEGER = -10 - Max non morti (molto non morti)

Dalle costanti simboliche sopra, iniziamo a ottenere un quadro mentale della vitalità, della morte e della "non morte" (e possibili ramificazioni o conseguenze) per i nostri mostri nel nostro gioco D&D. Senza queste parole (costanti simboliche), ci rimangono solo i numeri che vanno da -10 .. 10. Solo l'intervallo senza le parole ci lascia in un luogo di grande confusione e potenzialmente con errori nel nostro gioco se diverse parti del gioco hanno dipendenze da ciò che quell'intervallo di numeri significa per varie operazioni come attack_elveso seek_magic_healing_potion.

Pertanto, quando cerchiamo e consideriamo la sostituzione di "numeri magici", vogliamo porre domande molto mirate sui numeri nel contesto del nostro software e persino su come i numeri interagiscono semanticamente tra loro.

Conclusione

Rivediamo quali domande dovremmo porre:

Potresti avere un numero magico se ...

  1. Il valore di base può avere un significato o uno scopo speciale nel tuo universo software?
  2. Il significato o lo scopo speciale può essere probabilmente sconosciuto, inconoscibile, poco chiaro o confuso, anche nel suo contesto appropriato?
  3. È possibile utilizzare in modo improprio un valore di base adeguato con conseguenze negative in un contesto errato?
  4. È possibile utilizzare correttamente un valore di base improprio con conseguenze negative nel giusto contesto?
  5. Il valore di base ha relazioni semantiche o di scopo con altri valori di base in contesti specifici?
  6. Può esistere un valore di base in più di un posto nel nostro codice con semantica diversa in ciascuno, causando così una confusione al nostro lettore?

Esaminare i valori di base costanti manifest autonomi nel testo del codice. Poni ogni domanda lentamente e con attenzione su ogni istanza di tale valore. Considera la forza della tua risposta. Molte volte, la risposta non è in bianco e nero, ma ha sfumature di significato e scopo incompresi, velocità di apprendimento e velocità di comprensione. C'è anche la necessità di vedere come si collega alla macchina software che lo circonda.

Alla fine, la risposta alla sostituzione è rispondere alla misura (nella tua mente) della forza o debolezza del lettore per stabilire la connessione (ad es. "Ottenerlo"). Più rapidamente capiscono significato e scopo, meno "magia" hai.

CONCLUSIONE: Sostituisci i valori di base con costanti simboliche solo quando la magia è abbastanza grande da causare difficoltà a rilevare bug derivanti da confusioni.


1
Grazie. In seguito, gli strumenti di analisi statica che i miei colleghi continuano a installare continuano a lamentarsi dei numeri magici, ma come si suppone che uno strumento comprenda la semantica? Il risultato è che TUTTI i valori di base vengono sostituiti con costanti simboliche. Siccome sono d'accordo con le tue conclusioni, trovo che questo non sia l'ideale.
Chomeh,

17

Un numero magico è una sequenza di caratteri all'inizio di un formato file o scambio di protocollo. Questo numero funge da controllo di integrità.

Esempio: apri qualsiasi file GIF, vedrai all'inizio: GIF89. "GIF89" è il numero magico.

Altri programmi possono leggere i primi caratteri di un file e identificare correttamente le GIF.

Il pericolo è che i dati binari casuali possano contenere questi stessi caratteri. Ma è molto improbabile.

Per quanto riguarda lo scambio di protocollo, è possibile utilizzarlo per identificare rapidamente che l'attuale "messaggio" che viene passato all'utente è danneggiato o non valido.

I numeri magici sono ancora utili.


13
Non credo sia il numero magico a cui si riferiva
Marcio Aguiar,

4
Forse dovresti rimuovere i tag "file-format" e "networking" che hai aggiunto perché chiaramente non sta parlando di quel tipo di numeri magici.
Landon,

9
È ancora molto utile sapere che i numeri magici possono riferirsi a qualcosa di più di un semplice problema di codice. -Adam
Adam Davis,

3
Se il soggetto legge: "Che cos'è un numero magico in termini di codice sorgente", i tag non dovrebbero essere lì. Ma non ha specificato questo. Quindi avere le mie informazioni extra è buono. Penso che Kyle, Landon e Marcio abbiano torto.
Brian R. Bondy,

4
Inoltre non c'era modo di determinare quale stesse cercando. Dato che ero il primo post, non riuscivo a indovinare quale cercasse.
Brian R. Bondy,

12

Nella programmazione, un "numero magico" è un valore a cui dovrebbe essere assegnato un nome simbolico, ma è stato invece inserito nel codice come letterale, di solito in più di un posto.

È negativo per lo stesso motivo per cui SPOT (Single Point of Truth) è buono: se si desidera modificare questa costante in un secondo momento, è necessario cercare il codice per trovare ogni istanza. È anche negativo perché potrebbe non essere chiaro agli altri programmatori cosa rappresenta questo numero, quindi la "magia".

Le persone a volte prendono ulteriormente l'eliminazione dei numeri magici, spostando queste costanti in file separati per fungere da configurazione. Questo a volte è utile, ma può anche creare più complessità di quanto valga la pena.


Puoi essere più specifico sul perché eliminare i numeri di maginc non è sempre buono?
Marcio Aguiar,

In formule matematiche come e ^ pi + 1 = 0
Jared Updike,

5
Marcio: Quando fai cose come "const int EIGHT = 8;" e quindi i requisiti cambiano e si finisce con "const int EIGHT = 9;"
jmucchiello,

6
Siamo spiacenti, ma questo è semplicemente un esempio di cattiva denominazione o un utilizzo di base per la costante.
Kzqai,

1
@MarcioAguiar: su alcune piattaforme, un'espressione simile (foo[i]+foo[i+1]+foo[i+2]+1)/3può essere valutata molto più velocemente di un ciclo. Se uno dovesse sostituire il 3senza riscrivere il codice come un ciclo, qualcuno che vedeva ITEMS_TO_AVERAGEdefinito come 3potrebbe immaginare di poterlo cambiare 5e avere il codice in media più elementi. Al contrario, qualcuno che guardasse l'espressione con il letterale si 3sarebbe reso conto che 3rappresenta il numero di elementi che vengono sommati.
supercat

10

Un numero magico può anche essere un numero con una semantica speciale codificata. Ad esempio, una volta ho visto un sistema in cui gli ID record> 0 venivano trattati normalmente, 0 stesso era "nuovo record", -1 era "questa è la radice" e -99 era "questa è stata creata nella radice". 0 e -99 farebbero in modo che WebService fornisse un nuovo ID.

La cosa negativa di questo è che stai riutilizzando uno spazio (quello di numeri interi con segno per ID record) per abilità speciali. Forse non vorrai mai creare un record con ID 0 o con un ID negativo, ma anche in caso contrario, ogni persona che guarda il codice o il database potrebbe inciampare su questo e potrebbe essere inizialmente confusa. Va da sé che quei valori speciali non erano ben documentati.

Probabilmente, 22, 7, -12 e 620 contano anche come numeri magici. ;-)


10

Un problema che non è stato menzionato con l'uso dei numeri magici ...

Se ne hai moltissime, le probabilità sono ragionevolmente buone di avere due scopi diversi per i quali stai usando numeri magici, in cui i valori sembrano essere gli stessi.

E poi, abbastanza sicuro, è necessario modificare il valore ... per un solo scopo.


Questo non sembra molto probabile quando si parla di numeri (almeno non per me), ma mi sono imbattuto in stringhe ed è un successo: prima devi leggere molto codice per vedere dove viene usato, poi tu devo notare che viene utilizzato per cose diverse ... non per il mio passatempo preferito.
Tomislav Nakic-Alfirevic,

4

Presumo che questa sia una risposta alla mia risposta alla tua domanda precedente. Nella programmazione, un numero magico è una costante numerica incorporata che appare senza spiegazione. Se appare in due posizioni distinte, può portare a circostanze in cui un'istanza viene modificata e non un'altra. Per entrambi questi motivi, è importante isolare e definire le costanti numeriche al di fuori dei luoghi in cui vengono utilizzate.


3

Ho sempre usato il termine "numero magico" in modo diverso, come un valore oscuro memorizzato in una struttura di dati che può essere verificato come un rapido controllo di validità. Ad esempio i file gzip contengono 0x1f8b08 come i loro primi tre byte, i file di classe Java iniziano con 0xcafebabe, ecc.

Spesso vedi numeri magici incorporati nei formati di file, perché i file possono essere inviati in modo piuttosto promiscuo e perdere qualsiasi metadata su come sono stati creati. Tuttavia, i numeri magici vengono talvolta utilizzati anche per strutture di dati in memoria, come le chiamate ioctl ().

Un rapido controllo del numero magico prima dell'elaborazione del file o della struttura dei dati consente di segnalare tempestivamente gli errori, piuttosto che schlep fino in fondo attraverso un'elaborazione potenzialmente lunga al fine di annunciare che l'input era balderdash completo.


2

Vale la pena notare che a volte nel proprio codice si desiderano numeri "hardcoded" non configurabili. Ce ne sono alcuni famosi tra cui 0x5F3759DF che viene utilizzato nell'algoritmo di radice quadrata inversa ottimizzato.

Nei rari casi in cui trovo la necessità di utilizzare tali numeri magici, li imposto come const nel mio codice e documento il motivo per cui vengono utilizzati, come funzionano e da dove provengono.


1
Secondo me, l'odore del codice numerico magico si riferisce specificamente a costanti inspiegabili . Finché li stai inserendo in una costante nominata, non dovrebbe essere un problema.
Don Kirkby,

2

Che dire di inizializzare una variabile nella parte superiore della classe con un valore predefinito? 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 predefinito è ok. Non voglio fare:

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

Ciò rende più difficile la lettura? Non l'ho mai considerato fino a quando non ho installato CheckStyles.


Penso che andrebbe bene se il costruttore inizializza il valore. Altrimenti se il valore viene inizializzato al di fuori del costruttore, lo vedo solo come una seccatura e come qualcosa di più difficile da leggere.
Thomas Eding,

Penso che le static finalcostanti siano eccessive quando le stai usando in un metodo. Una finalvariabile dichiarata all'inizio del metodo è IMHO più leggibile.
Eva

0

@ eed3si9n: suggerirei persino che "1" è un numero magico. :-)

Un principio correlato ai numeri magici è che ogni fatto trattato dal tuo codice dovrebbe essere dichiarato esattamente una volta. Se usi numeri magici nel tuo codice (come l'esempio di lunghezza della password fornito da @marcio, puoi facilmente finire per duplicare quel fatto, e quando capisci che quel fatto cambia hai un problema di manutenzione.


5
Il codice IOW dovrebbe essere scritto in questo modo: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
Thomas Eding

0

Che dire delle variabili di ritorno?

Lo trovo particolarmente difficile quando si implementano le procedure memorizzate .

Immagina la prossima procedura memorizzata (sintassi errata, lo so, solo per mostrare un esempio):

int procGetIdCompanyByName(string companyName);

Restituisce l'ID dell'azienda se esiste in una tabella particolare. Altrimenti, restituisce -1. In qualche modo è un numero magico. Alcuni dei consigli che ho letto finora dicono che dovrò davvero progettare qualcosa del genere:

int procGetIdCompanyByName(string companyName, bool existsCompany);

A proposito, cosa dovrebbe restituire se la società non esiste? Ok: imposterà esistesCompany come false , ma restituirà anche -1.

Un'altra opzione è fare due funzioni separate:

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

Quindi una pre-condizione per la seconda procedura memorizzata è quella società esiste.

Ma ho paura della concorrenza, perché in questo sistema un'azienda può essere creata da un altro utente.

La linea di fondo a proposito è: cosa ne pensi di usare quel tipo di "numeri magici" che sono relativamente conosciuti e sicuri di dire che qualcosa non ha successo o che qualcosa non esiste?


In quel caso specifico, se la documentazione della funzione indica che un valore di ritorno negativo indica che non è stata trovata alcuna società, non c'è motivo di utilizzare una costante.
Vincent Fourmond,

-1

Un altro vantaggio dell'estrazione di un numero magico come costante offre la possibilità di documentare chiaramente le informazioni aziendali.

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();
         }
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.