Design Object Oriented: Factory method

Spesso ci accontentiamo di scrivere programmi funzionanti e questo sarebbe già un successo, direbbe qualcuno. ;-) A volte però non ci accorgiamo che i nostri programmi, anche se svolgono il loro compito, non contengono un codice elegante, non hanno cioè un buon design. La ricerca dell'eleganza del codice non è un mero esercizio estetico. Scrivere bel codice significa avere programmi facili da comprendere, quindi facili da cambiare e da correggere.
Vedremo qui e nei prossimi post alcune tecniche che, se bene applicate, possono aiutarci a raggiungere questi obiettivi.

Supponiamo in questo caso di avere una classe che possieda diversi costruttori, specializzati per ottenere oggetti simili ma con caratteristiche leggermente diverse. Possiamo immaginare inoltre che, dopo l'inizializzazione, sia necessario invocare dei metodi "setter" prima di poter utilizzare i nostri oggetti. Per esempio, in un programma di gestione di una azienda, vi sia una classe RisorsaUmana.

 
public class RisorsaUmana {
  private final String nome;
  private Ruolo ruolo;
  private boolean turnista;
  private RisorsaUmana responsabile;
 
  public RisorsaUmana(String nome, Ruolo ruolo) {
    this(nome, ruolo, null);
  }
 
  public RisorsaUmana(String nome,
                      Ruolo ruolo,
                      RisorsaUmana responsabile) {
    this.nome = nome;
    this.ruolo = ruolo;
    this.turnista = false;
    this.responsabile = responsabile;
  }
 
  public void setTurnista(boolean turnista) {
    this.turnista = turnista;
  }
 
  public static RisorsaUmana creaOperaio(String nome,
                                         boolean turnista,
                                         RisorsaUmana responsabile) {
    RisorsaUmana operaio = new RisorsaUmana(nome,
                                            Ruolo.OPERAIO,
                                            responsabile);
    operaio.setTurnista(turnista);
    return operaio;
  }
 
  public static RisorsaUmana creaImpiegato(String nome,
                                           RisorsaUmana responsabile) {
    return new RisorsaUmana(nome, Ruolo.IMPIEGATO, responsabile);
  }
 
  public static RisorsaUmana creaAmministratoreDelegato(String nome) {
    return new RisorsaUmana(nome, Ruolo.AMMINISTRATORE_DELEGATO);
  }
}
 

Per rendere omogenea ed espressiva la costruzione di un oggetto RisorsaUmana sono stati creati i factory method creaOperaio, creaImpiegato e creaAmministratoreDelegato, ognuno dei quali ha un insieme di parametri significativi per la particolare risorsa coinvolta. I vantaggi di questo approccio sono:

  • comunica che tipi di istanze sono disponibili meglio di quanto facciano i costruttori;
  • in presenza di diversi costruttori non devo scegliere quello più adatto all'oggetto da creare;
  • non rischio di dimenticare di impostare dei valori tramite dei setter prima di rendere disponibile un nuovo oggetto.

Lascia un commento

You must be logged in to post a comment.