I metodi che restituiscono una hashmap di stringa su oggetto devono essere evitati?

1

Nel mio codice attuale ho sentito il desiderio di avere più volte dei metodi di supporto che generano una collezione di oggetti e di restituirli come una mappa di una stringa all'oggetto, con la stringa come id univoca come l'etichetta degli oggetti. Molti dei miei oggetti hanno etichette uniche generiche poiché queste etichette vengono utilizzate tramite un'interfaccia riposante quando si esegue una query sull'oggetto.

La ragione per cui voglio farlo è l'efficienza. Potrei avere una collezione di dimensioni decenti e so che il metodo che chiama qualsiasi metodo di helper privato che ho scritto vorrà sicuramente cercare oggetti specifici all'interno della mia collezione, quindi restituirli come una mappa consente invece al metodo di chiamata di essere eseguito in O (n) di O (n ^ 2).

Tuttavia, ritengo che il ritorno non sia auto-documentato. La chiave è solo una stringa, non c'è nulla che renda ovvio che la stringa sia specificamente l'etichetta degli oggetti. Ovviamente avrò commenti in tal senso, ma idealmente il codice di auto-documentazione è scritto così bene che non è necessario andare alle delirazioni del metodo per capire qualcosa.

Quindi ho alcune domande:

1) Il fatto di trovarmi a dover restituire mappe un odore di codice è di per sé? (altro quindi forse l'ottimizzazione prematura, che so che potrei essere un po 'colpevole, ma non mi sento troppo male per preoccuparmi del grande O di un metodo)

2) Questo è generalmente accettabile, o dovrei cercare un approccio più pulito? Ad esempio, dovrei creare un oggetto mappa che esegue automaticamente la mappatura di qualsiasi oggetto per etichetta? Per quanto riguarda i luoghi in cui voglio restituire una mappa in cui la chiave è una chiave diversa, dovrei creare un oggetto wrapping per tutti loro? o la mia mappa è abbastanza buona?

EDIT:

Sono stati richiesti maggiori dettagli, per chiarire la mia situazione specifica. Sto lavorando all'interno di java. Anche se potrei avere stringhe univoche non sono conosciute fino al momento della compilazione e le enumerazioni non sono una buona scelta, altrimenti le avrei usate! Non sto usando la riflessione o altri sistemi per generare dinamicamente i dati, i metodi e il loro significato sono praticamente standard ogni volta. Di solito si utilizza l'equivalente di un UUID degli oggetti (che in questo caso è una stringa utilizzata in tutto il dominio), o l'etichetta, che è una stringa univoca garantita utilizzata per fare riferimento all'oggetto in questione per una chiamata riposante.

    
posta dsollen 09.05.2014 - 23:36
fonte

2 risposte

3

La decisione dipende da molte cose:

  • Il metodo del chiamante riconosce (al momento del codice) la struttura della mappa?
    Quando dico "code-time" intendo che quando scrivi il codice hai in mente una struttura specifica (rispetto al tempo di compilazione e al runtime). Se non lo fai, e il metodo dovrebbe essere in grado di gestire qualsiasi struttura ti passi (ad esempio, un metodo per convertire quella mappa in formato JSON), allora non hai davvero bisogno di documentare quella struttura al di fuori del metodo che crea la mappa, poiché non ha bisogno di essere referenziata da un essere umano al di fuori dell'ambito di quel metodo.

  • Stai utilizzando un linguaggio digitato statico o dinamico?
    I linguaggi dinamici tendono a dipendere meno da strutture dati ben definite. In JavaScript, ad esempio, non vi è alcuna differenza tra un oggetto e una mappa e Ruby ha OpenStruct che crea oggetti che sono sia strutture che mappe. Quando non hai un sistema di tipo strong, dovresti essere meno severo riguardo alla scrittura di codice di auto-documentazione a livello di API.

  • La lingua che usi fornisce un modo migliore di fare ciò che vuoi?
    Ad esempio, molti linguaggi tipizzati statici hanno tipi enumerati e spesso è possibile utilizzare questi tipi di enumerazione come chiavi di una mappa anziché come stringa. Questo ti permetterà di avere il codice di auto-documentazione che desideri (la dichiarazione del tipo di enum è una lista di tutte le chiavi usate in quella mappa) pur essendo in grado di scorrere tutte le coppie chiave-valore senza usare il reflection.

Se fornisci ulteriori dettagli, potremmo essere in grado di fornire ulteriore assistenza.

    
risposta data 10.05.2014 - 00:53
fonte
2

Should methods returning a hashmap of string to object be avoided?

Sì, se stai usando una lingua tipizzata staticamente, object dovrebbe essere evitato. Significa che devi eseguire il cast per fare qualcosa di significativo con il risultato, il che significa che devi modificare qualsiasi codice di gestione quando aggiungi un nuovo tipo. Non va bene.

E string dovrebbe essere evitato come chiave per una funzione / dizionario. Le stringhe sono facili da digitare / digitare erroneamente. Spesso le stringhe hanno implicato contratti a loro associati: se chiedo "pippo", voglio recuperare un Bar . Non appena non ottieni la roba di Bar , a runtime. Non va bene.

Is the fact that i find myself needing to return maps a code-smell in itself?

Per le mappe questo generico, sì - per le lingue tipizzate in modo statico. Vuol dire che vuoi qualcosa qualsiasi cosa che riguarda la peggiore violazione del principio di responsabilità individuale che puoi avere. Ciò implica anche l'inclusione dei tuoi contratti, che sposta gli errori dal tempo di compilazione a quello di esecuzione, aumentando il costo di fissarli e il rischio che essi raggiungano la produzione.

Is this generally acceptable, or should I be looking into a cleaner approach?

Dovresti sempre cercare un approccio più pulito, ma in non pochi casi hai davvero bisogno di qualcosa di così generico. Se stai facendo la serializzazione, hai davvero bisogno di una stringa per la mappa degli oggetti ... L'obiettivo qui è isolare la mancanza di digitazione il più possibile. Avere alcune classi che conoscono le possibili stringhe e i contratti impliciti. Spingi il disegno in modo che queste classi cambino raramente. Fai esplodere rumorosamente e rapidamente quando i contratti sono violati.

... e tutto questo esce dalla finestra se stai lavorando in un linguaggio dinamico. Praticamente tutto c'è già una mappa da una stringa all'altra (che è un'altra mappa di una stringa all'oggetto), quindi il meglio che puoi fare è suonare e provare come un pazzo.

    
risposta data 10.05.2014 - 01:08
fonte

Leggi altre domande sui tag