Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Guida al Visual Basic .NET - Il miglior codice

Guida al Visual Basic .NET

Capitolo 51° - Il miglior codice

<< Precedente Prossimo >>


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 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à 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.


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.
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 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 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 


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.
Detto questo, le seguenti direttive specificano quando usare quale tipo di notazione:
  • 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 privati : Camel
  • Variabili locali : Camel
  • Parametri : Camel
  • Nomi di controlli : Ungherese
  • Nomi costituiti da acronimi: All se di 2 caratteri, altrimenti Pascal


<< Precedente Prossimo >>
A proposito dell'autore

C#, TypeScript, java, php, EcmaScript (JavaScript), Spring, Hibernate, React, SASS/LESS, jade, python, scikit, node.js, redux, postgres, keras, kubernetes, docker, hexo, etc...