Sono tutti a favore dei prefissi fatti bene .
Penso che la notazione ungherese (di sistema) sia responsabile della maggior parte del "cattivo rap" che i prefissi ottengono.
Questa notazione è in gran parte inutile nei linguaggi fortemente tipizzati, ad es. In C ++ "lpsz" per dirti che la tua stringa è un puntatore lungo a una stringa nul terminata, quando: architettura segmentata è storia antica, le stringhe C ++ sono da comuni puntatori convenzionali a nul-terminato array di caratteri, e non è poi così difficile sapere che "customerName" è una stringa!
Tuttavia, utilizzo i prefissi per specificare l' utilizzo di una variabile (essenzialmente "App ungherese", anche se preferisco evitare il termine ungherese a causa della sua cattiva e ingiusta associazione con il sistema ungherese), e questo è un risparmio di tempo molto utile e approccio per la riduzione dei bug .
Io uso:
- m per i membri
- c per costanti / readonlys
- p per puntatore (e pp per puntatore a puntatore)
- v per volatile
- s per statico
- i per indici e iteratori
- e per eventi
Laddove desidero chiarire il tipo , utilizzo i suffissi standard (ad esempio Elenco, ComboBox, ecc.).
Questo rende il programmatore consapevole dell'uso della variabile ogni volta che la vede / la usa. Probabilmente il caso più importante è "p" per il puntatore (perché l'uso cambia da var. A var-> e bisogna stare molto più attenti con i puntatori - NULL, aritmetica dei puntatori, ecc.), Ma tutti gli altri sono molto utili.
Ad esempio, puoi utilizzare lo stesso nome di variabile in più modi in una singola funzione: (qui un esempio C ++, ma si applica ugualmente a molte lingue)
MyClass::MyClass(int numItems)
{
mNumItems = numItems;
for (int iItem = 0; iItem < mNumItems; iItem++)
{
Item *pItem = new Item();
itemList[iItem] = pItem;
}
}
Puoi vedere qui:
- Nessuna confusione tra membro e parametro
- Nessuna confusione tra indice / iteratore ed elementi
- Utilizzo di un insieme di variabili chiaramente correlate (elenco di elementi, puntatore e indice) che evitano le numerose insidie di nomi generici (vaghi) come "count", "index".
- I prefissi riducono la digitazione (più breve e funzionano meglio con il completamento automatico) rispetto a alternative come "itemIndex" e "itemPtr"
Un altro grande punto degli iteratori di "iName" è che non indicizzo mai un array con l'indice errato e se copio un ciclo all'interno di un altro ciclo non devo refactificare una delle variabili dell'indice del ciclo.
Confronta questo esempio irrealisticamente semplice:
for (int i = 0; i < 100; i++)
for (int j = 0; j < 5; j++)
list[i].score += other[j].score;
(che è difficile da leggere e spesso porta all'uso di "i" dove "j" era inteso)
con:
for (int iCompany = 0; iCompany < numCompanies; iCompany++)
for (int iUser = 0; iUser < numUsers; iUser++)
companyList[iCompany].score += userList[iUser].score;
(che è molto più leggibile e rimuove tutta la confusione sull'indicizzazione. Con il completamento automatico negli IDE moderni, questo è anche veloce e facile da digitare)
Il prossimo vantaggio è che i frammenti di codice non richiedono alcun contesto per essere compreso. Posso copiare due righe di codice in un'e-mail o in un documento e chiunque legga quel frammento può dire la differenza tra tutti i membri, costanti, puntatori, indici, ecc. Non devo aggiungere "oh, e stai attento perché "data" è un puntatore a un puntatore ", perché si chiama 'ppData'.
E per lo stesso motivo, non devo spostare gli occhi da una riga di codice per capirlo. Non devo cercare nel codice per scoprire se "dati" è un locale, un parametro, un membro o una costante. Non devo spostare la mano sul mouse, quindi posso passare il puntatore su "dati" e quindi attendere che venga visualizzata una descrizione comandi (che a volte non viene mai visualizzata). In questo modo i programmatori possono leggere e comprendere il codice in modo significativamente più veloce, perché non perdono tempo a cercare su e giù o ad aspettare.
(Se non pensi di perdere tempo a cercare su e giù per elaborare le cose, trova un po 'di codice che hai scritto un anno fa e che non hai mai visto da allora. Apri il file e salta a metà circa senza leggerlo. Scopri come lontano puoi leggere da questo punto prima di non sapere se qualcosa è un membro, un parametro o un locale. Ora passa a un'altra posizione casuale ... Questo è ciò che facciamo tutti tutto il giorno quando passiamo attraverso il codice di qualcun altro o cercando di capire come chiamare la loro funzione)
Il prefisso 'm' evita anche la brutta e prolissa notazione "this->" e l'incoerenza che garantisce (anche se stai attento di solito finirai con una miscela di "this-> data" e "dati" nella stessa classe, perché nulla impone una ortografia coerente del nome).
la notazione "questa" ha lo scopo di risolvere l' ambiguità , ma perché qualcuno dovrebbe scrivere deliberatamente un codice che può essere ambiguo? L'ambiguità sarà portare ad un bug, prima o poi. E in alcune lingue "questo" non può essere utilizzato per i membri statici, quindi è necessario introdurre "casi speciali" nel proprio stile di codifica. Preferisco avere un'unica semplice regola di codifica che si applica ovunque: esplicita, inequivocabile e coerente.
L'ultimo grande vantaggio è con Intellisense e il completamento automatico. Prova a utilizzare Intellisense su un Windows Form per trovare un evento: devi scorrere centinaia di misteriosi metodi di classe base che non dovrai mai chiamare per trovare gli eventi. Ma se ogni evento avesse un prefisso "e", verrebbero automaticamente elencati in un gruppo sotto "e". Pertanto, il prefisso funziona per raggruppare i membri, i cons, gli eventi, ecc. Nell'elenco intellisense, rendendo molto più semplice e veloce trovare i nomi desiderati. (Di solito, un metodo potrebbe avere circa 20-50 valori (locali, parametri, membri, cons, eventi) che sono accessibili nel suo ambito. Ma dopo aver digitato il prefisso (voglio usare un indice ora, quindi digito 'i. .. '), mi vengono presentate solo 2-5 opzioni di completamento automatico.
Sono un programmatore pigro e la convenzione di cui sopra mi fa risparmiare molto lavoro. Posso programmare più velocemente e commetto molti meno errori perché so come utilizzare ogni variabile.
Argomenti contro
Quindi, quali sono i contro? Argomenti tipici contro i prefissi sono:
"Gli schemi dei prefissi sono cattivi / cattivi" . Sono d'accordo che "m_lpsz" e il suo genere sono scarsamente pensati e del tutto inutili. Ecco perché ti consiglierei di usare una notazione ben progettata progettata per supportare le tue esigenze, piuttosto che copiare qualcosa di inappropriato per il tuo contesto. (Usa lo strumento giusto per il lavoro).
"Se cambio l'uso di qualcosa devo rinominarlo" . Sì, certo che lo fai, questo è il refactoring e perché gli IDE hanno strumenti di refactoring per svolgere questo lavoro in modo rapido e indolore. Anche senza prefissi, cambiare l'utilizzo di una variabile quasi sicuramente significa che il suo nome dovrebbe essere cambiato.
"I prefissi mi confondono e basta" . Come ogni strumento fino a quando non impari come usarlo. Una volta che il tuo cervello si è abituato ai modelli di denominazione, filtrerà automaticamente le informazioni e non ti dispiacerà davvero che i prefissi siano più lì. Ma devi usare uno schema come questo solidamente per una settimana o due prima di diventare davvero "fluente". Ed è allora che molte persone guardano il vecchio codice e iniziano a chiedersi come siano mai riuscite senza un buon schema di prefissi.
"Posso solo guardare il codice per elaborare questa roba" . Sì, ma non è necessario perdere tempo a cercare altrove nel codice o a ricordare ogni piccolo dettaglio di esso quando la risposta è proprio nel punto in cui l'occhio è già focalizzato.
(Alcune) di tali informazioni possono essere trovate semplicemente aspettando che venga visualizzata una descrizione comandi sulla mia variabile . Sì. Se supportato, per alcuni tipi di prefisso, quando il codice viene compilato in modo pulito, dopo un'attesa, è possibile leggere una descrizione e trovare le informazioni che il prefisso avrebbe trasmesso all'istante. Ritengo che il prefisso sia un approccio più semplice, più affidabile e più efficiente.
"Sta scrivendo di più" . Veramente? Un altro personaggio in più? O lo è - con gli strumenti di completamento automatico IDE, spesso ridurrà la digitazione, poiché ogni carattere prefisso restringe significativamente lo spazio di ricerca. Premi "e" e i tre eventi della tua classe compaiono in intellisense. Premere "c" per elencare le cinque costanti.
"Posso usare this->
invece di m
" . Bene, sì, puoi. Ma questo è solo un prefisso molto più brutto e più prolisso! Solo comporta un rischio molto maggiore (specialmente nei team) perché per il compilatore è facoltativo e quindi il suo utilizzo è spesso incoerente. m
d'altra parte è breve, chiaro, esplicito e non facoltativo, quindi è molto più difficile commettere errori nell'usarlo.