Replace Constructors with Creation Methods

Continuando la serie di post sui smells, inizio ad introdurre i possibili smell e le relative possibili soluzioni.

Il primo che affronteremo riguarda una classe con 5 costruttori (anche se personalmente già 2 costruttori sono troppi):

 

public class Loan
{
    public Loan(string commitment, int riskRating, int maturity)
    public Loan(string commitment, int riskRating, int maturity, DateTime expiry)
    public Loan(string commitment, string outstanding, int riskRating, int maturity, DateTime expiry)
    public Loan(int capitalStrategy, string commitment, int riskRating, int maturity, DateTime expiry)
    public Loan(int capitalStrategy, string commitment, string outstanding, int riskRating, int maturity, DateTime expiry)
}

Ecco come si presenterà la classe una volta rifattorizzata:

public class Loan
{
    private Loan(int capitalStrategy, string commitment, string outstanding, int riskRating, int maturity, DateTime expiry)
    public static Loan createTermLoad(string commitment, int riskRating, int maturity)
    {
        return new Loan(-1, commitment, "", riskRating, maturity, DateTime.MinValue);
    }

    public static Loan createTermLoad(int capitalStrategy, string commitment,
                                      string outstanding, int riskRating, int maturity)
    {
        return new Loan(capitalStrategy, commitment, outstanding, riskRating, maturity,
                        DateTime.MinValue);
    }

    public static Loan createRevolver(string commitment, string outstanding,
                                      int riskRating, DateTime expiry)
    {
        return new Loan(-1, commitment, outstanding, riskRating, -1, DateTime.MinValue);
    }

    public static Loan createRevolver(int capitalStrategy, string commitment,
                                      string outstanding, int riskRating, int maturity)
    {
        return new Loan(capitalStrategy, commitment, outstanding, riskRating,
                        maturity, DateTime.MinValue);
    }

    public static Loan createRCTL(string commitment, string outstanding,
                                  int riskRating, int maturity, DateTime expiry)
    {
        return new Loan(-1, commitment, outstanding, riskRating, maturity, expiry);
    }

    public static Loan createRCTL(int capitalStrategy, string commitment,
                                  string outstanding, int riskRating, int maturity,
                                  DateTime expiry) 
    {
        return new Loan(capitalStrategy, commitment, outstanding, riskRating, maturity, expiry);
    }
}
Motivazione:

Perchè dovrei togliere i miei molteplici costruttori a favore di una seria di metodi statici?
I costruttori non comunicano qual'è la loro intenzione nel momento in cui istanziano la classe, così più costruttori abbiamo all'interno della nostra classe più è probabile che dovremo andare a controllare ogni singolo costruttore per capire cosa fa (cosa impensabile se neanche abbiamo i sorgenti).

Se servirà creare un costruttore con la stessa firma, ma che istanzia l'oggetto in maniera diversa, non si potrà inserire.

Se il software avrà una certa dimensione e tanti costruttori è probabile che molti di questi non verranno utilizzati e vi rimaranno lì perchè anche capire quali vengono usati e quali no è un lavoro molto complicato.

Benefici e non
+ Comunica quale tipo di istanza stiamo creando
+ Evita i limiti dei costruttori
+ E' più semplice trovare i metodi non usati
- E' un metodo non standard per istanziare gli oggetti. Così potreste trovarvi alcune classi con i costruttori classici e altre no.

 

Per questi post sto prendendo, molto, spunto da libro Refactoring To Patterns di Joshua Kerievsky.

 

posted @ giovedì 23 aprile 2009 00:46

Print

Comments on this entry:

# re: Replace Constructors with Creation Methods

Left by marco at 23/04/2009 12:15
Gravatar
scusa ma mi potresti spiegare:
E' più semplice trovare i metodi non usati

sarà l'ora mattutina ma non trovo nessuna differenza al riguardo

grazie ;)

# re: Replace Constructors with Creation Methods

Left by salvatore.difazio@gmail.com at 23/04/2009 12:38
Gravatar
@Marco
Dal mio punto di vista, e spero tu sia d'accordo con me, è più semplice trovare un metodo tramite il suo nome piuttosto che tramite la sua firma.

Insomma è più semplice trovare un:

creaIlMetodoDaStringaEData

se invece dovessi cercare MiaClasse con firma string, DateTime e hai nel codice i seguenti costruttori:

MiaClasse(string);
MiaClasse(string, DateTime);
MiaClasse(string, DateTime, int);
MiaClasse(string, DateTime, int, double);

capisci che è un pò più complicato.
Spero d'averti chiarito il dubbio

# re: Replace Constructors with Creation Methods

Left by salvatore.difazio@gmail.com at 23/04/2009 12:44
Gravatar
@Luca e neronotte:

sono d'accordo in parte con voi :)

Questi post vorrebbero farsi che, chi li legge, possa migliorare un pò per volta il codice che si scrive, senza grossi stravolgimenti :)

I post con patterns un pò più "complicati" verranno in seguito.
Comments have been closed on this topic.