Cosa c'è di sbagliato nel restituire l'hashtable dal metodo pubblico e quando ha senso farlo?


9

Quali sono i problemi di progettazione nel restituire una tabella hash da un metodo pubblico quando si desidera restituire più elementi invece di creare una classe e restituire l'oggetto di quello?

Se ha problemi, in quali circostanze ha senso farlo?

Come cambia la risposta a questa domanda a seconda che la lingua sia dinamica o no?

Modifica: per chiarire che le chiavi sarebbero costanti e fanno parte del codice, non dei dati. Qualcosa per cui in genere creiamo una classe. La domanda è perché sarebbe sbagliato usare hashtable invece se la creazione di una classe sembra davvero la scelta giusta.

Risposte:


11

Utilizzare una classe meglio definita come tipo restituito rispetto a una tabella hash che contiene un numero arbitrario di valori come coppie nome / valore.

  1. Il primo e più importante punto è: manutenibilità. Guardando il codice, un nuovo programmatore non può mai dire quali sono i valori restituiti dal metodo. Se una nuova persona non capisce questo guardando il codice, il codice non sarà utile e soggetto a errori ogni volta che qualcuno aggiungerà più chiave / valori a tali dati o migliorerà l'applicazione.

  2. I metodi sono contratti tra il chiamante e il servizio. La cosa più importante in un metodo è il loro input e output. Questi input e output dovrebbero essere facilmente leggibili e comprensibili e auto documentali. Se usi una classe Person come valore di ritorno che ha nome, cognome, età - È auto-documentante. Se si genera un Javadoc per questo, l'utente può navigare tra le classi per capirlo meglio. Se usi una tabella hash, devi spiegarla nei commenti che nessuno leggerà o aggiornerà quando le cose cambiano.

  3. Non è possibile utilizzare generici come HashMap<String,String>nel caso in cui si desideri aggiungere un numero (diciamo età) alla dichiarazione di ritorno. Se non usi generici, dovrai lanciare avanti e indietro tra l'oggetto per il tipo reale. Puoi salvarlo se usi la digitazione dinamica.

  4. Inoltre, ci sono più possibilità di errori di runtime rispetto alla rilevazione dei problemi in fase di compilazione. ad es. se qualcuno cancella una voce dalla hashmap e uno dei vecchi chiamanti si aspetta la voce, il client fallisce durante il runtime. È sempre meglio rilevare questo problema in tempo di compilazione.

  5. Sarà difficile restituire un tipo immutabile se si desidera utilizzare l'hashmap come tipo restituito e così via. Ma se usi un utente definito il tuo tipo, puoi controllarlo.

Sarai tentato di usare un hashmap come tipo di ritorno perché puoi evitare di creare un paio di classi all'inizio, ma sarà un incubo mantenere il codice in futuro. Vai orientato agli oggetti !!!!


1
Sembra che tu abbia capito correttamente la domanda. Grazie.
Muhammad Hasan Khan,

8

Uno dei problemi sarebbe che in molti casi la chiave per la tabella hash sarebbe una stringa. Quindi i consumatori del metodo dovrebbero sapere in anticipo quali chiavi utilizzare per estrarre i dati. Ciò darebbe il potenziale per errori dovuti a errori di ortografia durante l'accesso ai dati.

Un altro svantaggio è la rifattabilità. Se in seguito decidi di cambiare il nome di un membro, allora hai un sacco di stringhe magiche che devono anche cambiare. È molto più semplice rinominare un membro della classe utilizzando gli strumenti di refactoring forniti dalla maggior parte degli IDE validi. Con una tabella hash probabilmente dovresti fare un'operazione di ricerca / sostituzione su tutti i file sorgente che potrebbe essere problematica.

Infine, perderai il tempo di compilazione del controllo dell'accesso dei membri, sia in termini di nome che di tipo. Quest'ultimo non è un problema se la tua tabella hash contiene solo un tipo di oggetto, ma se ne contiene molti (anche nella stessa catena gerarchica) vuoi davvero sfruttare il sistema di tipi della tua lingua e farti controllare il tempo di compilazione. Nella maggior parte degli IDE avrai una sorta di funzionalità intellisense / di completamento automatico - funzionano guardando il sistema dei tipi, ma non saranno in grado di aiutarti con le chiavi della tabella hash.

Per quanto riguarda i momenti in cui sarebbe opportuno restituire una tabella hash (o altra tale raccolta di coppie di valori chiave), lo useresti quando sia i valori che le chiavi non sono noti al momento della compilazione. Ad esempio, se si dispone di un metodo che analizza una stringa di query e restituisce le chiavi e i valori corrispondenti, una tabella hash sarebbe una buona scelta. In questo caso dovresti anche pensare a restituire una sorta di tabella hash immutabile o di sola lettura.

Modifica - La maggior parte dei punti sollevati in questa risposta cessano di essere applicabili quando si parla di lingue dinamiche :)


E se la lingua fosse dinamica?
Muhammad Hasan Khan,

Non sono un esperto di linguaggi dinamici, quindi qualcun altro può probabilmente fornire una risposta migliore per questo. Ma so che i linguaggi dinamici non eseguono comunque il controllo del tipo di tempo di compilazione. Ma in tal caso la restituzione di un oggetto e la restituzione di una tabella hash non sono così diverse ..
MattDavey

3
@Hasan Khan: in tal caso potrebbe non esserci alcuna differenza tra un'istanza di hash e un'istanza di classe. Ad esempio, in Javascript tutti gli oggetti sono hashtables e object.property è esattamente la stessa cosa di object ['property']
Michael Borgwardt

"Con una tabella hash probabilmente dovresti fare un'operazione di ricerca / sostituzione su tutti i file di origine che potrebbe essere problematica." Solo se hai scelto chiavi scadenti e non hai mai provato a scomporre quelle standard in modo che siano definite in un unico posto ...
Donal Fellows

7

L'argomento più importante contro questo sarebbe che stai esponendo troppe informazioni al consumatore. Il codice che consuma deve solo sapere che è una raccolta di valori-chiave (dizionario) di qualche tipo; che sia implementato come hashmap, un elenco di associazioni, un trie o quant'altro, è relativamente poco interessante. Quindi il modo corretto sarebbe quello di tornare da un'interfaccia adatta ( IDictionaryo qualunque sia la tua lingua preferita) anziché dal tipo reale.

Tutto questo supponendo che in realtà hai bisogno di un dizionario per rappresentare i tuoi dati, cioè i tuoi dati sono costituiti da coppie chiave / valore, in cui le chiavi sono univoche nel set di dati e non possono essere riparate al momento della compilazione. Se si dispone di chiavi pre-conosciute, è necessario creare un tipo appropriato (o diversi, come richiesto) per i dati. Dipende dal fatto che tu consideri le chiavi stesse come parte dei dati o parte del codice.

MODIFICA :

Per chiarire, sto usando il termine dizionario per indicare qui il tipo più generico di struttura di dati valore-chiave; Non intendo alcuna implementazione specifica del linguaggio come Python dicto .NET Dictionary.


1
+1 per "Dipende dal fatto che tu consideri le chiavi stesse come parte dei dati o parte del codice." - È un buon modo per dirlo. Non sono sicuro di quanto sia universale, ad esempio, il termine "dizionario" rispetto a "mappa".
MattDavey,

Restituire il dizionario non era previsto. le chiavi facevano parte del codice e non dei dati.
Muhammad Hasan Khan,

La vera domanda è il ragionamento dietro "Dovresti creare un tipo adeguato". La domanda è perché?
Muhammad Hasan Khan,

2

Una domanda che mi pongo è "stanno cambiando le chiavi in ​​questo dizionario?" Se sono costanti, è necessario restituire un oggetto o un'altra struttura dati appropriata. Se sono dinamici, potresti voler restituire una sorta di struttura in stile dizionario. Infine, se ci sono alcune chiavi che saranno costanti e un insieme sconosciuto di chiavi dinamiche, potresti voler restituire una struttura di dati ibrida che includa alcuni valori fissi e una sorta di dizionario per l'overflow.


In effetti il ​​tuo consiglio è corretto, ma la domanda è cosa c'è di sbagliato nel scegliere di usare la tabella hash quando la classe è una scelta migliore.
Muhammad Hasan Khan,

Non è / o; una classe può contenere facilmente un dizionario se ne hai bisogno.
Wyatt Barnett,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.