Come risolvere i metodi con lo stesso nome e tipi di parametri?

5

In molti casi, voglio scrivere metodi che hanno la stessa funzionalità per diversi tipi di input. Ciò può essere facilmente ottenuto sovraccaricando il metodo se i tipi di parametro sono diversi.

Ma qual è il modo migliore (il più robusto) per risolvere il caso quando i tipi di parametro sono gli stessi (cioè due diverse rappresentazioni dei dati con lo stesso tipo)?

Un esempio di questo sarebbe una matrice di interi che può essere naturalmente memorizzata come int[][] . Ma cosa succede se vuoi scrivere un metodo che accetta anche la trasposizione della matrice? La trasposizione è anche un int[][] ma una rappresentazione chiaramente diversa del tutto.

Posso vedere un paio di modi per farlo:

  • Fornire i metodi con nomi diversi
  • Aggiunta di un flag al metodo
  • Disposizione di ogni rappresentazione in classi diverse

Penso che il terzo metodo sia il modo più chiaro per farlo. Sfortunatamente sto lavorando su alcune librerie ad alte prestazioni dove non è una soluzione fattibile.

    
posta tskuzzy 14.01.2012 - 01:47
fonte

6 risposte

10

Io voto per l'opzione " Assegnazione dei diversi tipi di metodi ", specialmente se le prestazioni sono importanti.

Non utilizzare method1(int[][]) e method2(int[][]) .
Utilizza method(int[][]) e method_transposed(int[][]) per esempio.

Il nome del metodo dovrebbe sempre aiutare il lettore a capire cosa fa.

    
risposta data 14.01.2012 - 02:15
fonte
4

Devi essere attento a progettare API che hanno metodi sovraccaricati sul tipo di parametro: i metodi devono fare esattamente le stesse cose, altrimenti gli utenti saranno confusi.

Due metodi che prendono una matrice, uno che prende un "dritto" e l'altro che ne fa uno trasposto, sicuramente non stanno facendo la stessa cosa, quindi sovraccarichi su tipi diversi sono improbabili.

Scegliere un "flag" contro "nome diverso" è semplice: se il tuo metodo è simile a questo

int[][] mul(int[][] a, int[][] b, bool flag) {
    if (flag) {
        // Do one thing
    } else {
        // Do another thing
    }
}

allora dovresti usare metodi separati. Se il tuo metodo con un flag condivide una grande quantità di codice, dovresti usare un metodo con un flag.

    
risposta data 14.01.2012 - 02:14
fonte
1

Utilizza nomi di metodi diversi se i tipi di parametro sono gli stessi. Abbastanza semplice, no?

    
risposta data 14.01.2012 - 01:55
fonte
0

Non so in che lingua ci si trova, ma probabilmente una struttura o una tupla raggrupperebbe l'int [] [] più una bandiera in un "thingy" con prestazioni accettabili, e si tradurrà in un'interfaccia più pulita. In caso contrario, penso che la cosa più logica di una classe stia scoppiando quello che altrimenti sarebbe il tipo di classe in un altro parametro (forse un'enumerazione o qualcosa piuttosto che una bandiera per mantenere le opzioni più aperte). E tu sceglieresti consapevolmente la velocità su un'interfaccia più pulita. È possibile controllare la velocità per assicurarsi che sia importante, se le matrici sono 1.000 per 1.000, potrebbe non avere importanza. Anche se immagino che questo ti sia già venuto in mente.

    
risposta data 14.01.2012 - 02:15
fonte
0

Non utilizzare lo stesso tipo di dati per rappresentazioni diverse. Se si dispone di una matrice e di una versione "rappresentazione trasposta-di-una-matrice" del proprio metodo, potrebbe essere una buona idea creare due tipi di dati per queste rappresentazioni. In questo modo, il compilatore ti urlerà anche se utilizzi accidentalmente quello sbagliato da qualche parte.

    
risposta data 14.01.2012 - 10:27
fonte
0

Questo è il caso d'uso perfetto per le interfacce; Utilizzare una singola classe base per incapsulare la logica aziendale, ma implementare interfacce diverse in sottoclassi che richiedono parametri variabili. Questo illustra perfettamente il motivo per cui dovresti codificare su un'interfaccia, piuttosto che un'implementazione. Quindi sì, dovresti usare classi diverse, ma dovresti farlo

public class MatrixOne implements ThisMatrix {
  //code
}

public class MatrixTwo implements TransposeMatrix {
  //code
}

Ovviamente, questa è una semplificazione. Ci sono altre opzioni, ma se riesci a passare un messaggio che indica quale versione della matrice è efficace, puoi dire al ricevente come elaborarla, anche.

    
risposta data 14.01.2012 - 11:05
fonte

Leggi altre domande sui tag