Il metodo richiede l'implementazione concreta della raccolta. Devo cambiare tutti i metodi upstream per restituire implementazioni concrete?

1

Ho un metodo processDataAssumingLinkedHashMapInput() che elabora Map . Il Map deve essere un LinkedHashMap ordinato dai valori. I dati provengono da getStrIntMap(query) . Questo metodo ottiene resultSet da SQL e lo inserisce in LinkedHashMap. Ecco il codice:

public void processDataAssumingLinkedHashMapInput(){
    String query = "select MYID, MYVALUE from MYTABLE order by MYVALUE";
    Map<String, Integer> map = SQLTools.getStrIntMap(query);

    for (Map.Entry<String, Integer> entry : rawEntryToSortOrderMap.entrySet()) {
        //do something, assuming that values are ordered
    }
    //do more stuff
}

//SQLTools method, used by multiple other classes
public static Map<String, Integer> getStrIntMap(String query){
    Map<String, Integer> map = new LinkedHashMap<>();
    //ResultSet to map 
    return map;
}

La mia preoccupazione è che se qualcuno decide di cambiare getStrIntMap(String query) in Map<String, Integer> map = new HashMap<>(); (ad esempio per motivi di prestazioni) si romperà processDataAssumingLinkedHashMapInput() . Posso cambiare il tipo di ritorno di getStrIntMap all'implementazione concreta, ma non sarebbe bello e qualcuno lo cambierà in un Map astratto. Sono in grado di creare due metodi essenzialmente identici uno dei quali restituisce Map e l'altro restituisce LinkedHashMap , ma ciò interromperà il principio DRY. Posso riordinare i dati all'inizio del metodo processDataAssumingLinkedHashMapInput , ma questo di nuovo viola la regola DRY. Qual è la migliore pratica per questo caso?

    
posta Stepan 02.02.2017 - 17:05
fonte

3 risposte

0

Usa un po 'di IoC. Refactor per consentire al chiamante di iniettare l'istanza della mappa, che consentirà ad altri sviluppatori di utilizzare la mappa più efficiente e di utilizzare la mappa con le funzionalità desiderate.

public static void fillStrIntMap(String query, Map<String, Integer> map){
    //ResultSet to map 
}
    
risposta data 03.02.2017 - 01:15
fonte
4

Suggerisco di aggiungere un metodo alla libreria che compila un Map vuoto fornito dal chiamante dal query fornito.

Mantenendo le cose ASCIUTTE, il metodo getStrIntMap invocherà questo altro metodo passando un nuovo LinkedHashMap e restituendo quel Map (come interfaccia, quindi la sua firma rimane invariata).

Quindi il chiamante può scegliere lo standard getStrIntMap che restituisce l'interfaccia Map per l'accoppiamento libero, oppure, il chiamante può scegliere l'altro passaggio in un Map di sua scelta in modo che possa avere chiare garanzie che la mappa è in effetti un LinkedHashMap , e tuttavia, l'API della libreria non deve mai esporre tipi concreti.

    
risposta data 02.02.2017 - 18:30
fonte
2

Una possibilità è creare un nuovo tipo astratto chiamato OrderedMap che estenda la Mappa astratta e restituisca quello. In questo modo il metodo restituisce ancora un'astrazione, ma ora viene applicata la restituzione di un tipo di mappa ordinato. I chiamanti esistenti possono ancora considerare l'oggetto restituito come una mappa di base, se lo desiderano, o essere sicuri che l'oggetto restituito sia ordinato con l'implementazione protetta contro l'essere idly modificato per restituire, ad esempio, HashMap.

    
risposta data 02.02.2017 - 18:57
fonte

Leggi altre domande sui tag