I getters portano al peccato

Io credo profondamente nella debolezza umana, in particolare sono un convinto assertore della debolezza del programmatore, e mi piace essere debole. Se avessi una gran forza di volontà potrei creare tutti i getters che voglio e semplicemente “decidere di non usarli”. Sarebbe un po’ ridicolo forse, quindi penso che, debole o forte che uno sia, è il caso di non scrivere mai un getter.

Ma perchè non dovrei usare i getters? Se il mio obiettivo è mantenere un’architettura agile (quindi con le chiusure giuste) non c’è niente di peggio dell’infrazione del criterio di Demeter. Demeter è subdolo, se lo infrangi puoi pensare di passarla liscia per un po’, ma alla fine non solo ti troverai con del pessimo design, ma anche con una tale rete di relazioni che qualsiasi tentativo di identificare delle astrazioni sarebbe futile. In quel caso io penso che l’unica soluzione sia fregarsene del design, puntare solo a rimuovere tutte le chiamate che infrangono Demeter, e poi da lì partire con la rifattorizzazione verso i principi di design.

Quindi, qual’è il modo migliore per infrangere la legge di Demeter?

Tipicamente un programmatore che lavori in un linguaggio ad oggetti ha ben chiara soprattutto una cosa, perchè gli è stata detta alla prima lezione di “programmazione ad oggetti” : gli oggetti incapsulano i dati, non si dovrebbe accedere mai direttamente ai dati.

Questa, ovviamente nella mia umilissima opinione, è una scemata galattica, perchè gli oggetti non incapsulano i dati per mestiere, questo è incidentale, gli oggetti rappresentano del comportamento nella sua interezza, e quindi posseggono le procedure, più tutto ciò che serve alle procedure, che possono essere dati, o altri oggetti, o nient’altro, è del tutto secondario.

Detto questo, il suddetto assioma insegna al programmatore (chiamiamolo ingenuo) qualcosa che si può applicare meccanicamente : tutti i campi di un oggetto devono essere privati. Essendo meccanico costa poca fatica mentale, ma dà tanta soddisfazione, ti fa sentire un grande designer.

Quindi, pensando al caso peggiore, del programmatore più ingenuo, dovremmo* almeno poter dare per assunto che metterà tutti i campi privati, irraggiungibili per virtù della sintassi. E questo, incidentalmente, ci protegge da infrangere Demeter. Quando il nostro programmatore si troverà a dover implementare una nuova feature si sentirà a disagio a rendere non-privati i campi che gli servono, e quindi abbiamo una piccola protezione.

*[Questo non è sempre vero, il vero caso peggiore scrive tutto public e tutto static, ma lasciamo da parte i freaks]

Creare dei getters, metodi non-privati che espongono un campo dell’oggetto è il modo migliore per cancellare anche questa piccola protezione : il nostro programmatore non ha ricevuto nessun condizionamento riguardo al livello di accesso dei metodi. Il getter, in quanto metodo, e quindi non tabu, lo mette in grado di fare quello che voleva fare sin dall’inizio : accedere a quello che gli serve per scrivere questa dannata feature; senza avere alcun senso di colpa.

I getters rendono dolce l’errore… una combinazione letale.

Io i getters li uso, ma non ho mai trovato un’occasione in cui questi fossero veramente necessari, c’è sempre un’alternativa che mi permetta di rispettare Demeter, non la seguo sempre, perchè, come dicevo all’inizio, sono debole, ma chissà perchè quando ho dei getters (comunque mai in un’interfaccia, sarebbe davvero troppo per il mio fegato) scopro sempre di avere :
a) troppe responsabilità in ogni classe
b) accoppiamento altissimo
c) poca astrazione
d) un sacco di mocks nei miei tests

In effetti, perchè mai i getters, a differenza dei campi pubblici, dovrebbero assicurare l’information hiding? Non nascondono un bel niente! E quindi come posso attendermi di avere uno qualsiasi dei benefici del design OO?

In verità, se proprio uno dovesse.. forse sarebbe meglio mettere un campo pubblico, almeno non ti viene voglia di farlo finire in un’interfaccia… ho già menzionato che vedere dei getters o dei setters in un’interfaccia mi fa venire le convulsioni?

P.S. un getter che in sè rappresenta la responsabilità di una classe (cioè non è un semplice passacarte ma contiene della logica)… tipo questo :

getSize(){return a*5/2}

non è un getter, è il metodo principale di SizeCalculator.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s