A48. Il miglior codice
Il fine giustifica i mezzi... beh non sempre. In questo caso mi sto riferendo allo stile in cui il codice sorgente viene scritto:
infatti, si può ottenere un risultato che all'occhio dell'utente del programma sembra buono, se non ottimo, ma che visto da un
programmatore osservando il codice non è per niente affidabile.
Quando si pubblicano i propri programmi open source, con sorgenti annessi, si dovrebbe fare particolare attenzione anche a come si scrive,
permettendo agli altri programmatori di usufruire del proprio codice in maniera veloce e intuitiva. In questo modo ne trarranno vantaggio
non solo gli altri, ma anche voi stessi, che potreste trovarvi a rivedere uno stesso sorgente molto tempo dopo la sua stesura e non ricordarvi
più niente. A tal proposito, elencherò ora alcune buone norme da seguire per migliorare il proprio stile.
Commentare
È buona norma commentare il sorgente nelle sue varie fasi, per spiegarne il funzionamento o anche solo lo scopo. Mentre il commento può essere
tralasciato per operazione straordinariamente lampanti e semplici, dovrebbe diventare una regola quando scrivete procedure funzioni o anche solo
pezzi di codice più complessi o creati da voi ex novo (il che li rende sconosciuti agli occhi altrui).
Vi faccio un piccolo esempio:
X = Math.Sqrt((1 - (Y ^ 2 / B ^ 2)) * A ^ 2)Questo potrebbe essere qualsiasi cosa: non c'è alcuna indicazione di cosa le lettere rappresentino, nè del perchè venga effettuata proprio quell'operazione. Riproviamo in questo modo, con il sorgente commentato, e vediamo se capite a cosa la formula si riferisca:
Così è molto meglio: possiamo capire sia lo scopo della formula sia il procedimento logico per mezzo del quale ci si è arrivati.'Data l'equazione di un'ellisse: 'x^2 y^2. '--- + --- = 1 'a^2 b^2 'Ricava x: 'x^2 / a^2 = 1 - (y^2 / b^2) 'x^2 = (1 - (y^2 / b^2)) * a^2 'x = sqrt((1 - (y^2 / b^2)) * a^2) X = Math.Sqrt((1 - (Y ^ 2 / B ^ 2)) * A ^ 2)
Dare un nome
Quando si creano nuovi controlli all'interno della windows form, i loro nomi vengono generati automaticamente tramite un indice, preceduto
dal nome della classe a cui il controllo appartiene, come, ad esempio, Button1 o TabControl2. Se per applicazioni veloci, che devono svolgere
pochissime, semplici operazioni e per le quali basta una finestra anche piccola, non c'è problema a lasciare i controlli innominati in questo
modo, quasi sempre è utile, anzi, molto utile, rinominarli in modo che il loro scopo sia comprensibile anche da codice e che il loro nome sia
molto più facile da ricordare. Troppe volte vedo nei sorgenti dei TextBox3, Button34, ToolStripItem7 che non si sa cosa siano. A mio parere,
invece, è necessario adottare uno stile ben preciso anche per i nomi. Dal canto mio, utilizzo sempre come nome una stringa composta per i primi
tre caratteri dalla sigla del tipo di controllo (ad esempio cmd o btn per i button, lst per le liste, cmb per le combobox, txt per le textbox e
così via) e per i rimanenti da parole che ne descrivano la funzione. Esemplificando, un pulsante che debba creare un nuovo file si chiamerà
cmdNewFile (cmd=command, il vecchio controllo vb6 da cui non mi sono mai staccato), una lista che debba contenere degli indirizzi di posta sarà
lstEmail: quest'ultima notazione è detta "notazione ungherese". A tal proposito, vi voglio suggerire
quest'articolo e vi invito caldamente a leggerlo.
Variabili
E se il nome dei controlli deve essere accurato, lo deve essere anche quello delle variabili. Programmare non è fare algebra, non si deve credere
di poter usare solo a, c, x, m, ki eccetera. Le variabili dovrebbero avere dei nomi significativi. Bisogna utilizzare le stesse norme sopra
descritte, anche se a mio parere il prefisso per i tipi (obj è object, sng single, int integer...) si può anche tralasciare.
Risparmiare memoria
Risparmiare memoria renderà anche le operazioni più semplici per il computer. Spesso è bene valutare quale sia il tipo più adatto da utilizzare,
se Integer, Byte, Double, Object o altri. Perciò bisogna anche prevedre quali saranno i casi che si potrano verificare. Se steste costruendo un
programma che riguardi la fisica, dovreste usare numeri in virgola mobile, ma quali? Più è alta la precisioe da utilizzare, più vi servirà
spazio: se dovete risolvere problemi da liceo userete il tipo Decimal (28 decimali, estensione da -7,9e+28 a 7,9e+28), o al massimo Single
(38 decimali, estensione da -3,4e+38 a +3,4e+38), ma se state facendo calcoli specialistici ad esempio per un acceleratore di particelle
(megalomani!) avreste bisogno di tutta la potenza di calcolo necessaria e usereste quindi Double (324 decimali, estensione da -1,7e308 a
+1,7e+308). Ricordatevi anche dell'esistenza dei tipi Unsigned, che vi permettono di ottenere un'estensione di numeri doppia sopra lo zero,
così UInt16 avrà tanti numeri positivi quanti Int32.
Il rasoio di Occam
La soluzione più semplice è quella esatta. E per questo mi riferisco allo scrivere anche in termini di lunghezza di codice. È inutile scrivere
funzioni lunghissime quando è possibile eguagliarle con pochissime righe di codice, più compatto, incisivo ed efficace.
Public Function Fattoriale(ByVal X as byte)As UInt64If X = 1Then Return 1Else Dim TAs UInt64 = 1For IAs Byte = 1To X T *= INext Return TEnd If End Function 'Diventa: Public Function Fattoriale(ByVal X as byte)As UInt64If X = 1Then Return 1Else Return X * Fattoriale(X - 1)End If End Function
Sub Copia(ByVal DaAs String ,ByVal AAs String )Dim RAs New IO.SreamReader(Da)Dim WAs New IO.StreamWriter(A) W.Write(R.ReadToEnd) R.Close() W.Close()End Sub 'Diventa IO.File.Copy(Da, A)'Spesso anche il non conoscere tutte le possibilità ' si trasforma in uno spreco di tempo e spazio
Incapsulamento
L'incapsulamento è uno dei tre fondamentali del paradigma di programmazione ad Oggetti (gli altri due sono polimorfismo ed ereditarietà, che
abbiamo già trattato). Come ricorderete, all'inizio del corso, ho scritto che il vb.net presenta tre aspetti peculiari e ve li ho spiegati.
Tuttavia essi non costituiscono il vero paradigma di programmazione ad oggetti e questo mi è stato fatto notare da Netarrow, che ringrazio :P.
Tratterò quindi, in questo momento tale argomento. Nonostante il nome possa suggerire un concetto difficile, non è complicato. Scrivere un
programma usando l'incapsulamento significa strutturarlo in sezioni in modo tale che il cambiamento di una di esse non si ripercuota sul
funzionamento delle altre. Facendo lo stesso esempio che porta Wikipedia, potreste usare tre variabili x, y e z per determinare un punto e poi
cambiare idea e usare un array di tre elementi. Se avete strutturato il programma nella maniera suddetta, dovreste modificare leggermente solo
i metodi della sezione (modulo, classe o altro) che è impegnata nella loro modifica e non tutto il programma.Convenzioni di denominazione
Nei capitoli precedenti ho spesse volte riportato quali siano le "convenzioni" per la creazione di nomi appositi, come quelli per le proprietà
o per le interfacce. Esistono anche altri canoni, stabiliti dalla Microsoft, che dovrebbero rendere il codice migliore in termini di
velocità di lettura e chiarezza. Prima di elencarli, espongo una breve serie di definizioni dei tipi di nomenclatura usati:
- Pascal Case : nella notazione Pascal, ogni parte che forma un nome deve iniziare con una lettera maiuscola, ad esempio una variabile che conetenga il percorso di un file sarà FileName, o una procedura che analizza un oggetto sarà ScanObject. Si consiglia sempre, in nomi composti da sostantivi e verbi, di anticipare i verbi e posticipare i sostantivi: il metodo per eseguire la stampa di un documento sarà PrintDocument e non DocumentPrint.
- Camel Case : nella notazione camel, la prima parte del nome inizia con la lettera minuscola, e tutte le successive con una maiuscola. Ad esempio, il titolo di un libro sarà bookTitle, o l'indirizzo di una persona address (un solo nome).
- Notazione Ungherese : nella notazione ungherese, il nome del membro viene composto come in quella Pascal, ma è preceduto da un prefisso alfanumerico con l'iniziale minuscola che indica il tipo di membro. Ad esempio una casella di testo (TextBox) che contenga il nome di una persona sarà txtName, o una lista di oggetti lstObject.
- All Case : nella notazione All, tutte le lettere sono maiuscole.
- Nome di un metodo : Pascal
- Campo di una classe : Pascal
- Nome di una classe : Pascal
- Membri pubblici : Pascal
- Membri protected : Pascal
- Campi di enumeratori : Pascal
- Membri prvati : Camel
- Variabili locali : Camel
- Parametri : Camel
- Nomi di controlli : Ungherese
- Nomi costituiti da acronimi: All se di 2 caratteri, altrimenti Pascal
The Totem's Lair - Copyright (C) 2009
È vietata la riproduzione sia totale che parziale del sito.



