Quando devono essere refactati i overload di metodo?

0

Quando dovrebbe codice che assomiglia a:

DoThing(string foo, string bar);

DoThing(string foo, string bar, int baz, bool qux);

...

DoThing(string foo, string bar, int baz, bool qux, string more, string andMore);

Essere refactored in qualcosa che può essere chiamato in questo modo:

var doThing = new DoThing(foo, bar);

doThing.more = value;
doThing.andMore = otherValue;

doThing.Go();

O dovrebbe essere refactored in qualcos'altro interamente?

Nel caso specifico che ha ispirato questa domanda, è un'interfaccia pubblica per una DLL di template XSLT in cui abbiamo dovuto aggiungere vari flag (di vari tipi) che non possono essere incorporati nell'input XML della stringa.

    
posta Ben Heley 29.10.2013 - 10:42
fonte

3 risposte

3

Credo che l'approccio comune sia quello di incapsulare alcuni (o tutti) i parametri in una classe e avere questo come parametro:

DoThing(string foo, string bar, DoThingParameters parameters = null);

Se usi C #, puoi scrivere quei parametri direttamente in linea quando chiami il metodo:

DoThing(foo, bar, new DoThingParameters { More = value, AndMore = otherValue });
    
risposta data 29.10.2013 - 11:23
fonte
1

Entrambi funzionano, anche se personalmente non mi piace assegnare membri pubblici o proprietà del genere se questi membri o proprietà sono utilizzati direttamente per uno scopo.

In altre parole, se si dispone di una classe di logger, non si dovrebbe assegnare "logger.message" e quindi chiamare "log ()", poiché il messaggio viene utilizzato esclusivamente per il metodo log, quindi dovrebbe essere passato .

Comprensibilmente, posso vedere la necessità di fare tali cose al fine di evitare il codice di refactoring. Ecco un paio di cose che potresti fare invece:

  1. Considera di passare parametri non specifici nel costruttore piuttosto che il metodo stesso. Ciò che intendo per parametri non specifici sono i parametri che non sono specifici di un particolare metodo ma il comportamento di controllo che non è probabile che cambi nell'istanza. Tornando all'esempio della classe logger, tale parametro potrebbe essere la directory in cui è salvato il file di registro.
  2. Considera di passare una mappa valori-chiave contenente tutti i parametri. Questo è il metodo preferito per passare comunque i parametri non descrittivi a librerie di terze parti. Se ti trovi a gestire grandi quantità di parametri da gestire, potrebbe essere preferibile. Un buon esempio di ciò potrebbe essere l'istanziazione di una connessione al database utilizzando molti dei parametri specifici del database piuttosto che dover disporre di un metodo statico per ciascun database. Il metodo può quindi estrarre tutti i parametri che trova che può utilizzare. Tuttavia, ti consiglio che se lo fai in questo modo consideri di eliminare le altre firme di metodo e costringi tutte le chiamate a utilizzare questo sistema di valori-chiave per coerenza.

Spero che ti aiuti!

    
risposta data 29.10.2013 - 11:10
fonte
0

Quello che stai affrontando qui è l'anti-pattern del costruttore telescopico.

IMHO si dovrebbe refactoring per i membri pubblici solo se si tratta di una classe semplice utilizzata per memorizzare i dati. Altrimenti, la tua classe sembra un buon candidato per il pattern Builder . Puoi usarlo per:

  • incapsula la logica dei valori membro predefinita: imposta tali valori all'interno del builder anziché impostarli per ciascun oggetto che costruisci utilizzando i suoi membri accesso pubblico

  • ottenere la capacità di rispondere all'inizializzazione inadeguata - quando l'oggetto è costruito dal builder che determina all'interno del builder cosa fare quando non sono stati impostati tutti i valori richiesti

risposta data 30.10.2013 - 12:14
fonte

Leggi altre domande sui tag