Metodi di denominazione che fanno la stessa cosa ma restituiscono tipi diversi

4

Supponiamo che stia estendendo una classe di selezione di file grafici ( JFileChooser ).

Questa classe ha metodi che visualizzano la finestra di dialogo selettore file e restituiscono una firma di stato sotto forma di int : APPROVE_OPTION se l'utente seleziona un file e fa clic su Apri / Salva , CANCEL_OPTION se l'utente colpisce Annulla e ERROR_OPTION se qualcosa va storto. Questi metodi sono chiamati showDialog() .

Trovo che questo sia macchinoso, quindi decido di creare un altro metodo che restituisca un oggetto File : nel caso di APPROVE_OPTION , restituisce il file selezionato dall'utente; altrimenti restituisce null . È qui che mi imbatto in un problema: sarebbe corretto per me mantenere il nome di showDialog() , anche se i metodi con quel nome - e un tipo diverso di ritorno - esistono già? Per finire, il mio metodo accetta un parametro aggiuntivo: un File che denota in quale directory deve essere avviato il selettore di file.

La mia domanda: è corretto chiamare un metodo con lo stesso nome di un metodo superclasse se restituiscono tipi diversi? O sarebbe confusionario per gli utenti API? (Se sì, quale altro nome potrei usare?)

In alternativa, dovrei mantenere il nome e cambiare il tipo di ritorno in modo che corrisponda a quello degli altri metodi?

public int showDialog(Component parent, String approveButtonText) // Superclass method
public File showDialog(Component parent, File location) // My method
    
posta Konstantin 10.11.2012 - 22:24
fonte

2 risposte

5

Perché è necessario estendere questo corso? E perché hai bisogno di denominare il tuo metodo come showDialog ?

In realtà il tuo metodo fa qualcosa di completamente diverso da ciò che showDialog fa. Un nome migliore per il tuo metodo sarebbe showDialogAtLocationAndReturnSelectedFile in quanto il tuo metodo fa più o meno queste cose. Assegnare un nome a showDialog confonderà solo gli utenti del codice.

Inoltre, senza sapere nient'altro, direi che stai cercando di spingere troppo in un unico metodo. Come reagisci su una stampa annullata? Che ne dici di un errore? Restituisci nulla? Se è così, stai forzando l'utente del codice a controllare il valore di ritorno ancora una volta. Questo ha il potenziale di essere solo un'altra "Leaky Abstraction" e le API Java ne hanno già abbastanza.

Una parte importante della progettazione dell'API è assicurarsi che il nome di una funzione / classe / metodo corrisponda a ciò che realmente fa. Ed è per questo che in JFileChooser il nome del metodo è showDialog . Mostra solo la finestra di dialogo. Non apre il file per la lettura, non esegue un controllo se il nome del file è valido e, onestamente, perché lo farebbe? L'utente del codice ha appena chiesto alla classe di mostrare la finestra di dialogo.

Il creatore di Ruby lo chiama il "Principio di Least Surprise" *, e anche se non conosco davvero Ruby, questa è una grande linea da cui imparare. Il tuo codice dovrebbe essere al servizio del suo utente, e una parte di questo servizio è incorporare il contratto del metodo / classe nel suo nome.

Potresti pensare che non stai progettando un'API, ma dubito che tu lavori da solo: probabilmente c'è qualcun altro nella squadra e apprezzeranno questo. Inoltre, raccomando vivamente questa lezione su API Design: Come progettare una buona API e perché è importante . È stato presentato ai googler da un designer Java, quindi è un problema.

Forse è più di quello che hai chiesto, ma sento che sembra che manchi un po 'il senso dei metodi di denominazione.

AGGIORNAMENTO: * Mi sembra di sbagliare, il creatore di Ruby ha in realtà dichiarato che ha progettato Ruby con il "Principio di Almeno stupore", non "Principio di Least Surprise". In ogni caso, quello che ho detto vale ancora.

    
risposta data 10.11.2012 - 23:05
fonte
1

Il problema principale che posso vedere con questo è che se utilizzo il tuo metodo in questo modo:

chooser.showDialog(parent,location).getPath()

funzionerà perfettamente il più delle volte, ma se l'utente cambia idea sul caricamento di un file e fa clic su Cancel, il programma si bloccherà. Potresti dire che non dovrei scrivere un codice del genere, e avresti ragione, ma a volte le persone scrivono un codice del genere. Il metodo come scritto non è conveniente, dal momento che devi ancora controllare null, ed è un po 'una trappola per chiunque non presti sufficiente attenzione.

Per quanto posso dire, stai cercando di astrarre 2 chiamate di metodo in una sola, ma è abbastanza probabile che il nuovo metodo sia altrettanto ingombrante dopo aver considerato la necessità di un controllo nullo. È possibile che l'intero flusso di lavoro con cui hai a che fare possa essere ragionevolmente astratto, nel qual caso qualsiasi cosa tu chiami l'intero flusso di lavoro potrebbe probabilmente essere un buon nome per un metodo.

Per rispondere alla tua domanda attuale, non penso che avere metodi con lo stesso nome che restituiscono tipi diversi sia automaticamente sbagliato, ma i nomi e i tipi di ritorno non dovrebbero mai confondere.

    
risposta data 10.11.2012 - 23:54
fonte

Leggi altre domande sui tag