Guida al Visual Basic .NET
Capitolo 51° - 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: '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) 'Prende la soluzione positiva: X = Math.Sqrt((1 - (Y ^ 2 / B ^ 2)) * A ^ 2)Così è molto meglio: possiamo capire sia lo scopo della formula sia il procedimento logico per mezzo del quale ci si è arrivati. Dare un nomeQuando 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à btnNewFile, 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.VariabiliE 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 memoriaRisparmiare 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.Ricordate, inoltre, di distruggere sempre gli oggetti che utilizzate dopo il loro ciclo di vita e di richiamare il rispettivo distruttore se ne hanno uno (Dispose). Il rasoio di OccamLa 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 UInt64 If X = 1 Then Return 1 Else Dim T As UInt64 = 1 For I As Byte = 1 To X T *= I Next Return T End If End Function 'Diventa: Public Function Fattoriale(ByVal X as byte) As UInt64 If X = 1 Then Return 1 Else Return X * Fattoriale(X - 1) End If End Function Sub Copia(ByVal Da As String, ByVal A As String) Dim R As IO.SreamReader(Da) Dim W As 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 IncapsulamentoL'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 denominazioneNei 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:
C#, TypeScript, java, php, EcmaScript (JavaScript), Spring, Hibernate, React, SASS/LESS, jade, python, scikit, node.js, redux, postgres, keras, kubernetes, docker, hexo, etc...
|