Come scrivere il codice
Post date: Oct 26, 2015 9:59:43 PM
Errori e soluzioni nella nomenclatura
Il nome classe
Errore: Usare i verbi. Usare Manager , Processor , Data , o Info.
Soluzione: Usare unicamente un nome.
In nome classe composto
Errore: Inserire avvolte la parte variabile e poi quella fissa e viceversa.
Soluzione: Inserire prima la parte che indica l'oggetto che subirà l'azione e poi quella che indica il contesto dell'azione. Es.: CardPayment, CashPayment, PayPalPayment
Il nome metodo
Errore: Usare un nome idiota Es: "YouMustDieBastard" al posto di "Kill"
Soluzione: Usare un verbo o una frase con un verbo, che descrivano in poche parole ciò che sono le responsabilità del metodo rispetto alla classe; cosa fà.
Il concetto che esprime il nome di un metodo
Errore: "YouMustDieBastard" è troppo lungo e complesso e/o che non descrive cosa fa la funzione
Soluzione: Un nome composto da una sola parola che espime il concetto base e cosa fa la funzione ("Kill")
Un nome ovvio
Errore: Non scrivere un nome che esprime un concetto ovvio ad uno sviluppatore.
Soluzione: "JobQueue" cosa vorrà mai dire?
Un nome che crea ambiguità
Errore: Assegnare il risultato della funzione getAccoutGroup() alla variabile accountsList
Soluzione: Se uso la parola "List" essa ha un significato specifico per un programmatore. Meglio assegnare ad una variabile semplicemente accountGroup o solo accounts
Il nome dell'overload di un costruttore
Errore: Usare un overload generico bastato sul solo nome della classe e i nuovi parametri può non essere sufficientemente chiaro
Soluzione: Usare un FACTORY METHOD per descrivere l'argomento.
String s = String.FromNumber(11); //invece di String s = new String(11);
Il contesto
Errore: Il principale segno di codice mal scritto è non riuscire a dedurre il contesto degli attori di una funzione
Soluzione: Se riusciamo ad identificare più attori e vogliamo separare i loro contesti, piuttosto che aggiungere un abbreviazione davanti al nome, è meglio creare una classe dedicata.
Ad esempio se uso le variabili: nome, cognome, eta, come faccio a sapere che sono di una persona e non mescolarle con le eventuali altre? Semplice, creo una classe persona e le sue proprità.
Cosa deve fare un metodo
Errore: Tante cose
Soluzione: Una sola; scrivere una funzione ha una sola responsabilità (SRP). Se ne fa più di una va suddivisa in altri metodi.
Switch con più funzioni
Errore: Cresce ad ogni nuovo case. Ha più responsabilità. Viola la SRP perché ha più di un motivo per essere modificata. Viola anche OCP perché deve cambiare ogni volta che viene aggiunto un nuovo tipo.
Soluzione: Nascondere lo switch in una ABSTRACT FACTORY.
Funzioni ad un argomento
Errore: Non si capisce come deve essere usato
Soluzione: Il nome della funzione deve fare capire come sarà usato il suo argometo. InputStream fileOpen("myFile"); oppure: writeFiled(name); capisco che il nome sarà quello di un campo.
Funzioni a due argomenti e parametri di output come argomento
Errore: Passare come parametro due argomenti che non hanno nulla a che fare con loro senza un ordine naturale o alcuna coesione, possono fare confusione, perché non si capisce come verrà usato l'uno e l'altro. Usare parametri di output se non strettamente necessario.
Soluzione: Se ho un parametro di out come argomento, è meglio fare diventare il metodo chiamato di proprietà dell'oggetto chiamante, e convertire la funzione ad un solo parametro. Oppure creare una terza classe e passare al costruttore l'oggetto chiamante e creare un metodo opportuno. In caso di parametri che servono per eseguire una azione, dare un nome descrittivo composto. Es: assertExpectedEqualsActual(expected, actual).
Funzione a tre parametri
Errore: Fa molta confusione
Soluzione: Se si puo', meglio evitarla.
No ai parametri bool
Errore: Passare parametri bool per fare fare qualcosa nella funzione
Soluzione: Creare 2 funzioni distinte
Nome funzione e side effects
Errore: Nome della funzione che non fa capire che verrà generato un side effect o viceversa. Se CheckPassword genera side effects (es.: apre la sessione) è un chiaro errore.
Soluzione: Scrivere nomi che fanno presumere chiaramente la presenza di un side effect. Initialize()
Funzione tutto fare (comandi e query)
Errore: Creare una funzione che lancia un comando per fare cambiare un oggetto e torna immediatamente un risultato.
Soluzione: Vanno creati due metodi distinti, vedi pattern COMMAND-QUERY SEPARATION.
Ritorno parametri
Errore: Non riuscire a capire cosa viene ritornato
Soluzione: Usare verbo e nome per l'oggetto/i. Ad esempio se ho un oggetto collezione chiamo: getItem() per il singolo, getList() per tutti
N.B.: In C# le proprietà non hanno la convenzione get e set nel nome, in C++ la metto io.
Inoltre se utilizzo get, presumo che non ci siano side effects nel metodo e che sia una pura funzione query
Errori e soluzioni nei commenti
Commenti
Errore: Commentare tutto.
Soluzione: Meglio rendere il codice parlante scrivendo i nomi delle classi, funzioni e variabili in modo significativo per chi legge.
// Il modulo dalla lista globale <mod> dipende dal sottosistema di cui facciamo parte? if (smodule.getDependSubsystems().contains(subSysMod.getSubSystem())) // Questo può essere scritto senza commenti così: ArrayList moduleDependees = smodule.getDependSubsystems(); String ourSubSystem = subSysMod.getSubSystem(); if (moduleDependees.contains(ourSubSystem))
Commenti nelle funzioni
Errore: Commentare cosa fa un pezzo di codice generando confusione per una cosa magari ovvia.
Soluzione: Meglio creare un metodo con il nome esplicito secondo le convenzioni viste sopra.
Commenti troppo lunghi
Errore: I commenti troppo lunghi (specie se basterebbe vedere come è scritto un metodo per capire cosa fa), generano confusione.
Soluzione: Creare un nome esplicito del metodo secondo le convenzioni viste sopra.
Come scriverli
Errore: Scrivere con tempi e verbi sempre diversi
Soluzione: Mentre la terza persona singolare, che probabilmente è il modo più corretto perché descrive appunto cosa fa quella riga di codice
Es.:
// avvia il programma
// carica i dati
// muove il cursore
// mostra l'immagine
// chiude la finestra
Errori e soluzioni nella gestione delle eccezzioni
Validazione dei parametri
Errore: Non validare i parametri di ingresso in una funzione secondo le pre-condizioni del caso
Soluzione: Validare l'input della funzione. Se non è possibile farlo prima, generare un eccezzione. Es.: html5Parser.parse(html); andrà a finire bene? Non lo so quindi in caso di non integrità genero un eccezzione.
Usare molte generazioni di eccezzioni
Errore: Usare molte, troppe generazioni di eccezzioni.
Soluzione: Le eccezzioni rappresentano appunto un caso eccezzionale. Se il caso è prevedibili meglio utilizzare un valore di ritorno booleano. Evitare di generare eccezzioni, se ho dati validi in condizioni normali. Es.: L'utente digita il nome o la password sbagliata. <- è un caso gestibile con booleano