Facciamo un
esempio:
public
double CalcolareIlPrezzoScontato(double
prezzo, double sconto)
{
//
implementare il corpo del metodo
}
- il metodo utilizza tipi primitivi che hanno significati diversi;
- solo il nome dei parametri evidenzia il loro significato;
- intuiamo dal nome del metodo che il valore di ritorno è un "prezzo";
- potrei passare al parametro prezzo lo sconto e viceversa;
public double X(double y, double z)
{
// implementare il corpo del metodo
}
Si si, concordo con voi, il metodo così definito non è molto
chiaro, però è esattamente lo stesso metodo.
Quindi cosa possiamo
fare per:
- migliorare la qualità del nostro codice?
- renderlo più leggibile?
- evitare errori banali?
- prezzo;
- sconto;
public
class Prezzo
{
public
double
Value { get;
set;
}
}
public class Sconto
{
public
double
Value { get;
set;
}
}
public
Prezzo X(Prezzo
y, Sconto z)
{
//
implementare il corpo del metodo
}
Sembra evidente che il metodo "X" prende in ingresso un
Prezzo e uno Sconto e restituisce un Prezzo che possiamo ipotizzare
scontato. Se vogliamo estremizzare il concetto potremmo creare una
struttura PrezzoScontato che deriva da Prezzo.
public class PrezzoScontato : Prezzo
{
}
Quindi il metodo si può mutare in:
public
PrezzoScontato X(Prezzo
y, Sconto z)
{
//
implementare il corpo del metodo
}
Ora è evidente qual è il comportamento di "X". Questo
ultimo passaggio può essere eccessivo, però è esattamente quello
che il metodo CalcolareIlPrezzoScontato risolveva.
Inoltre facciamo un'ulteriore ipotesi e pensiamo che inizialmente
i prezzi erano definiti come interi (software con valuta in lire) e anche lo sconto fosse di tipo intero (richiesta
esplicita del product owner).
public int CalcolareIlPrezzoScontato(int prezzo, int sconto)
Poi un bel giorno la comunità Europea si inveta l'euro e noi
(indovinate un po') dobbiamo modificare il nostro codice per
sostituire da int a double tutti i punti dove esiste il concetto di
prezzo.
Adoro la funzionalità find / replace.
Dopo qualche ora di
sostituzioni manuali, incrociamo le dita, eseguiamo il programma.
"bhe!!! dai sembra funzionare... fino al primo crash :-)"
Mentre continuiamo a capire cosa abbiamo sbagliato, arriva il
nostro adorato product owner e ci chiede: "ciao ragazzi, ho
pensato che mentre fate il cambio di valuta da lire a euro, vorrei
dare la possibilitá di inserire sconti anche con i decimali, tanto
non dovrebbe essere molto complicato...".
"Bene bene, io mi
licenzio."
Mentre il fantasma del "find/replace" aleggia
nell'aria, nella testa aleggia un pensiero "come potevo
evitare tutto questo?".
La risposta è facile, non dovevamo usare i tipi primitivi.
Infatti, se avessimo avuto le entità Prezzo e Sconto bastava
cambiare il tipo della proprietà Value da int a double e tutto era
sotto controllo.
Come potete vedere, l'uso di tipi primitivi per esprimere
concetti noti può portare ai dei seri problemi.