lunedì 12 gennaio 2015

Mutatis mutandis

Ultimamente si vedono diversi articoli sulla rete che parlano di oggetti immutabili.

Addirittura classi final con metodi final che non dovrebbero essere nemmeno estensibili per evitare che una sottoclasse possa modificane il comportamento.
Indubbiamente in un contesto multi thread questa pratica risolve in partenza il problema dell'accesso concorrente, tuttavia si pongono dei problemi di ordine pratico rilevanti: per esempio se un oggetto è la radice di un albero e si desidera cambiare il nome del nodo radice, trattandosi di oggetti immutabili, bisognerebbe creare un nuovo oggetto radice e clonare tutti i nodi figli, cioè clonare l'intero albero.

Un approccio che non prevede alcun metodo set potrebbe essere devastante per lo spreco di risorse, prima di tutto per quanto riguarda l'uso della memoria, per non parlare del tempo di esecuzione.
Un altro problema degli oggetti immutabili riguarda i riferimenti alle vecchie versioni degli oggetti, che andrebbero cambiati per aggiornarli ai nuovi.

Ci può essere però una soluzione intermedia e di buon senso che risolve il problema tra oggetti mutabili e oggetti immutabili: il comportamento.

Un oggetto ha una identità, definita da uno o più proprietà, ma ha anche un comportamento, cioè ci sono dei dati che di solito sono archiviati da qualche parte e che possono cambiare senza che si cambi l'identità dell'oggetto. Per esempio prendiamo un oggetto anagrafica che ha nome, cognome indirizzo, per semplicità non ne consideriamo altri. Ora, cambiare il nome e il cognome significa cambiare l'identità della persona, quindi sono campi immutabili, il cui cambiamento è giusto che generi un nuovo oggetto anagrafica. Diverso invece è il discorso per quanto riguarda l'indirizzo, che può cambiare e che dovrebbe riflettere un  dato sul database, cioè la modifica dell'indirizzo si dovrebbe tradurre in un aggiornamento di un campo su un record dell'archivio.

In questo modo il campo indirizzo è mutabile, ma l'oggetto non muta, muta soltanto il suo "comportamento".
Il concetto di comportamento è più intuitivo se pensiamo a un oggetto che abbia il nome di un giocatore e il suo punteggio, il nome definisce l'identità e dovrebbe essere immutabile, invece il punteggio è mutabile. Dal momento che il punteggio magari è archiviato in un unico luogo (potrebbe essere una cache ma questo complicherebbe questo ragionamento, perché una cache non è altro che una copia più veloce dei dati), il riferimento degli altri oggetti all'oggetto giocatore non cambia.

Potrebbe essere questo compromesso una soluzione di buon senso. Peccato che tutto il mondo Java Enterprise non si comporti in questo modo e gli entity siano a tutti gli effetti una cache che copia spesso il modello delle tabelle sul db, essendo oggetti completamente mutabili.

La domanda che ci si può porre a questo punto è se gli oggetti del dominio applicativo possano essere degli entity o se invece non sarebbe più corretto ricorrere a oggetti che facciano da proxy verso gli entity, facendo venire i capelli bianchi a qualche manager di progetto, per i tempi di sviluppo iniziale... chissà... lascio aperto il dubbio ma credo di sì.


Nessun commento:

Posta un commento