Factory e leggibilità del codice (1/2)

Uno degli obbiettivi a cui, sempre più spesso, cerco di porre attenzione, nella scrittura del codice, è la leggibilità: il codice che scrivo deve essere auto-esplicativo sia per “futuri lettori”, sia perchè la mia memoria (ormai troppo a corto raggio), non mi permette di ricordare il giorno successivo perchè il giorno precedente ho scritto quelle righe di codice…sarà l’età :-S

Questo assunto è sempre vero e sempre applicabile, ma diventa fondamentale (IMHO) quando la parte in gioco è il cuore del software che si sta sviluppando: il domain model.

Immergendoci nel mondo DDD (e nel suo UL) e prendendo in considerazione la fase di creazione di un aggregate root, le motivazioni per cui viene creata una nuova istanza di un oggetto sono essenzialmente due:

  • la creazione vera e propria di una nuova istanza
  • la reidratazione di un’istanza già persistita nel “data store”

Cerchiamo di analizzare il primo punto sviscerando come, cosa e perchè di un concetto abbastanza sottovalutato in DDD, ma che, a fronte della premessa di questo post, è per me di fondamentale importanza: la factory.

Per prima cosa distinguiamo il concetto di factory visto come “pattern” (GoF), dal punto di vista della factory “vista” in ottica DDD: il libro, analizza il pattern sotto un punto di vista tecnico (come e quando implementare un approccio del genere), la factory in DDD approccia la questione, inquadrando l’aspetto di creazione degli aggregate da un punto di vista semantico del modello.

La costruzione di un oggetto avviene attraverso il costruttore. E fin qui non ci piove. Ma pensiamoci un attimo: è giusto dare ad un oggetto le competenze per “autosetupparsi” nel modo corretto? A maggior ragione se quell’oggetto è un aggregate root? Ovviamente la risposta non c’è, ma, personalmente parlando, non è una pratica che mi piace molto e, dicendola tutta, per me vìola l’SRP principle. Ecco il primo motivo per cui introduco, spesso e voleventieri, la factory in stretta relazione ad un aggregate: la factory è l’unico punto del mio codice che sa come portare un aggregate root in uno stato consistente, prima di essere utilizzato.

L’altro aspetto, ancora più importante, anzi diventato quasi predominante è il rendere il codice il più esplicativo possibile: tramite il costruttore non ho modo di rendere evidente la semantica dell’operazione che sto eseguendo, tramite una factory ho la possibilità di creare più metodi che hanno lo stesso obbiettivo, creare un aggregate root, ma entry point potenzialemente differenti.

Un po’ di codice, che non guasta mai, vale più di mille parole:

In questo modo, utilizzando il costruttore, il perché ci sia la necessità di creare una nuova istanza di ordine è assolutamente nascosta a chi leggerà il nostro codice. E questo non è bello…

Introducendo la factory, tutto torna ad essere molto più parlante:

Con l’ingresso in scena della factory, abbiamo poi la possibilità di sfruttare il polimorfismo nella fase di creazione degli oggetti, cosa che, ovviamente, con il solo costruttore non possiamo fare. Fin qui mi sembra non ci sia nulla di nuovo e innovativo 🙂 Ma se siamo d’accordo fino a qui posso procedere con più serenità.

Ho volutamente lasciato i più generici possibile i parametri del primo metodo (e  ”Object[] params” mi sembra abbastanza generico), perchè anche i parametri dei metodi della factory ricoprono un ruolo fondamentale nella leggibilità del codice…ma di questo parliamo la prossima volta.