Does it make sense to declare private fields using an interface as their type?
Sì, lo fa. Per molte ragioni.
However, in my experience programmers normally declare variables to be of the exact type of the class that will be assigned to them, e.g. HashMap in this case. Why is this?
Finché non hanno scritto completamente il metodo, non sanno a cosa servirà l'accesso. Si potrebbe iniziare con l'interfaccia più restrittiva e passare a meno restrittive in base alle esigenze. Ma funzionerà contro gli strumenti di completamento del codice.
Iniziando con HashMap come HashMap e successivamente passando all'interfaccia più restrittiva teoricamente si ottiene lo stesso risultato. E significa che, mentre pensi a nuove cose che ti servono da HashMap, sono a portata di mano. Il problema è che le persone che lavorano in questo modo a volte dimenticano di fare il passaggio.
Per alcuni è più facile pensare a una HashMap come solo una HashMap quando si scrive codice. Dopo tutto, ci sono molte altre cose a cui pensare. Anche alcuni programmatori OOP ben addestrati fanno questo, non perché pensano che sia una buona pratica, ma perché non vogliono essere distratti mentre scrivono il codice. Questo è egoista perché non li ferisce tanto quanto fa male a coloro che vengono dopo. A volte intendevano dedicare del tempo al refactoring dell'interfaccia, ma non ci sono riusciti. Non guardare il codice scritto in questo modo come se fosse pensato per essere in questo modo. Questo è veloce e sporco.
Ma è privato! No getter. Nessun setter.
È vero che essere privati significa questo tipo di variabili e la sua stessa esistenza non è visibile al mondo esterno a meno che non sia passato in qualche oggetto esterno. Anche in quel caso il parametro del metodo / costruttore che lo riceve è quello che più ha bisogno di essere il più alto possibile nella catena di ereditarietà. Non è passato l'argomento (la nostra variabile).
Tuttavia, i buoni principi di codifica non riguardano solo gli oggetti. Alcuni possono risparmiare un sacco di problemi con un solo metodo.
Principi di progettazione rilevanti
- Programma su un'interfaccia, non un'implementazione
- Interfacce ruolo
- Prendi le decisioni in un unico posto
Programma su un'interfaccia
Diciamo che questa variabile è utilizzata in almeno un lungo metodo difficile da leggere. Se è dichiarata come una mappa e non qualcosa di concreto, posso immediatamente dire che potrei rifattorizzare qualsiasi implementazione cartografica senza nemmeno dover leggere il lungo metodo.
Interfaccia ruoli
Se il metodo lungo può andare avanti con la variabile ad un livello ancora più alto dovrebbe. Hai davvero bisogno di una mappa? Riesci a cavartela con una delle sue super interfacce che espone di meno? (Beh, la mappa non ha un'interfaccia super ma immagina di parlare di lista). Meno esposto, più alto è, più opzioni hai per cambiare senza problemi.
Prendi le decisioni in un unico posto
Dato che ho già dimostrato di non voler nemmeno leggere questo lungo e brutto metodo, dovrebbe essere una sorpresa che io non voglia attraversarlo modificando una serie di hashmap da mappare? (o qualche altra implementazione se ho voglia di trasmettere la miseria). Io non. Io davvero no. Per favore, non farmi. Per favore?