Devo restituire Collection o ImmutableCollection da un metodo?

5

Durante la scrittura di un'API in Java, restituendo una raccolta immutabile di qualche tipo, ho la possibilità di restituire Collection (o List , Map , ecc.) dal metodo o% gude% di guava (o ImmutableCollection , ImmutableList , ecc.):

private final ImmutableMap<> _immutableMap = ...

public Collection<T> getValues() {
    return _immutableMap.values();
}

o

public ImmutableCollection<T> getValues() {
    return _immutableMap.values();
}

Quale è meglio?

L'impostazione del valore di ritorno come ImmutableMap mi impone di usare quel tipo esatto per sempre, in modo che non possa scambiare ImmutableCollection per il mio tipo immutabile in seguito che restituisce, diciamo, una visualizzazione immutabile dei valori che isn _immutableMap (la costruzione di una richiede la copia dei valori, e non posso creare una sottoclasse per fornire una vista immutabile di una collezione mutevole).

Ma c'è un vantaggio per le persone che chiamano il metodo per vedere che il valore di ritorno è effettivamente immutabile e hanno i metodi t an ImmutableCollection e add contrassegnati come deprecati, piuttosto che provare ad aggiungere o rimuovere elementi e farlo fallire in fase di runtime .

In generale, mi piace restituire il tipo di interfaccia più specifico da un metodo, in modo da poter modificare l'implementazione sottostante in seguito, se necessario, senza interrompere il contratto. Ma c'è un vantaggio per i chiamanti che restituiscono un remove , al costo di limitare lo sviluppo futuro del metodo e causare futuri possibili problemi di prestazioni dovuti alla copia di tutti i valori in un ImmutableCollection invece di fornire una vista immutabile.

    
posta thecoop 17.12.2013 - 11:31
fonte

2 risposte

5

Normalmente raccomanderei di usare i tipi più astratti ( Collection , List etc) in questo caso.

I motivi:

  • Fornisce più flessibilità per restituire un tipo concreto diverso in futuro. Ad esempio, qualcuno potrebbe presentare un ImmutableList migliore di Guava.
  • Collection , List ecc sono più familiari per gli utenti.
  • È evita una dipendenza su Guava nella tua API pubblica. Evitare le dipendenze esterne è generalmente buono, usa le API standard ovunque sia possibile.

Se sei felice di impegnarti a utilizzare sempre le raccolte Guava, o se questa è solo un'API interna che non sarà ampiamente utilizzata da persone diverse, suppongo che non importi molto.

P.S. se la tua preoccupazione sta segnalando all'utente che il valore restituito è immutabile, ti suggerirei di trovare un altro modo per comunicarlo (annotazioni, documentazione, denominazione dei metodi, ecc.). Il sistema di tipo Java non è realmente progettato per comunicare fatti arbitrari sui tipi (alcuni sistemi di tipo più sofisticati lo tentano, ma è ancora un argomento di ricerca)

    
risposta data 17.12.2013 - 16:43
fonte
1

Generally, I like to return the most-specific interface type from a method

Probabilmente intendi il tipo meno specifico, perché è quello che ti permette di scambiare il tipo di risultato concreto con qualcosa di più specifico.

In generale, se vuoi rimanere aperto in questo modo, devi cercare l'antenato più adatto ai tipi che hai in mente, quindi camminare fino alla radice finché non pensi che non sia più adatto per il tipo di ritorno del tuo metodo.

Facciamo questo esempio concreto con le tue due classi:

ImmutableCollection extends Collection extends Iterable extends Object

e

List extends Collection extends Iterable extends Object

Chiaramente, il tuo antenato comune è Collection , quindi devi porsi la seguente domanda:

Would it be ok, if my callers got a Collection back instead of ImmutableCollection?

Credo che andrebbe bene, dato che stanno già assumendo comunque una collezione. Quindi diciamo che lo scrivi con Collection<T> come tipo di ritorno. È facile vedere che ora puoi semplicemente passare l'implementazione a un java.util.List non modificabile, senza che alcun codice client necessiti di una modifica.

In effetti perdi alcune informazioni come hai sottolineato non sapendo dal tipo, se il tuo Collection può essere modificato o meno. Ma questa è davvero una specie di aringa rossa, perché se apri Javadoc f.ex. del metodo add puoi facilmente leggere:

Throws:

UnsupportedOperationException - if the add operation is not supported by this collection

Quindi, mentre non si può più vedere dal tipo stesso, che la collezione è immutabile, non si ha nemmeno un tipo che dice chiaramente che è mutabile. In altre parole, Collection può essere letto come gestire con cura in entrambi i modi.

    
risposta data 17.12.2013 - 15:16
fonte

Leggi altre domande sui tag