Blog‎ > ‎Articoli‎ > ‎

Come scrivere il codice

pubblicato 26 ott 2015, 14:59 da Rudy Azzan   [ aggiornato in data 2 mar 2018, 08:26 ]

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
Comments