Ho questa funzione API:
public ResultEnum DoSomeAction(string a, string b, DateTime c, OtherEnum d,
string e, string f, out Guid code)
Non mi piace Perché l'ordine dei parametri diventa inutilmente significativo. Diventa più difficile aggiungere nuovi campi. È più difficile vedere cosa succede. È più difficile refactoring del metodo in parti più piccole perché crea un altro sovraccarico di passaggio di tutti i parametri nelle funzioni secondarie. Il codice è più difficile da leggere.
Mi è venuta l'idea più ovvia: avere un oggetto che incapsula i dati e passarli invece di passare ogni parametro uno per uno. Ecco cosa mi è venuto in mente:
public class DoSomeActionParameters
{
public string A;
public string B;
public DateTime C;
public OtherEnum D;
public string E;
public string F;
}
Ciò ha ridotto la mia dichiarazione API a:
public ResultEnum DoSomeAction(DoSomeActionParameters parameters, out Guid code)
Bello. Sembra molto innocente, ma in realtà abbiamo introdotto un enorme cambiamento: abbiamo introdotto la mutabilità. Perché quello che avevamo precedentemente fatto era in realtà passare un oggetto immutabile anonimo: parametri di funzione sullo stack. Ora abbiamo creato una nuova classe che è molto mutevole. Abbiamo creato la capacità di manipolare lo stato del chiamante . Che schifo Ora voglio il mio oggetto immutabile, cosa devo fare?
public class DoSomeActionParameters
{
public string A { get; private set; }
public string B { get; private set; }
public DateTime C { get; private set; }
public OtherEnum D { get; private set; }
public string E { get; private set; }
public string F { get; private set; }
public DoSomeActionParameters(string a, string b, DateTime c, OtherEnum d,
string e, string f)
{
this.A = a;
this.B = b;
// ... tears erased the text here
}
}
Come puoi vedere, ho ricreato il mio problema originale: troppi parametri. È ovvio che non è questa la strada da percorrere. Ciò che mi accingo a fare? L'ultima opzione per ottenere tale immutabilità è usare una struttura "di sola lettura" come questa:
public struct DoSomeActionParameters
{
public readonly string A;
public readonly string B;
public readonly DateTime C;
public readonly OtherEnum D;
public readonly string E;
public readonly string F;
}
Ciò ci consente di evitare costruttori con troppi parametri e raggiungere l'immutabilità. In realtà risolve tutti i problemi (ordinamento dei parametri ecc.). Ancora:
- Tutti (compresi FXCop e Jon Skeet) concordano sul fatto che esporre campi pubblici sia negativo .
- Eric Lippert e altri affermano che fare affidamento su campi di sola lettura per l'immutabilità è una bugia .
In quel momento mi sono confuso e ho deciso di scrivere questa domanda: qual è il modo più semplice in C # per evitare il problema "troppi parametri" senza introdurre la mutabilità? È possibile utilizzare una struttura di sola lettura a tale scopo e tuttavia non avere una cattiva progettazione API?
PRECISAZIONI:
- Si prega di supporre che non vi sia violazione del principio di responsabilità singola. Nel mio caso originale, la funzione scrive solo i parametri dati in un singolo record DB.
- Non sto cercando una soluzione specifica per la data funzione. Sto cercando un approccio generalizzato a tali problemi. Sono particolarmente interessato a risolvere il problema "troppi parametri" senza introdurre mutabilità o un design terribile.
AGGIORNARE
Le risposte fornite qui hanno diversi vantaggi / svantaggi. Pertanto, vorrei convertirlo in un wiki della comunità. Penso che ogni risposta con esempio di codice e pro / contro sarebbe una buona guida per problemi simili in futuro. Ora sto cercando di scoprire come farlo.
DoSomeActionParameters
tratta di un oggetto usa e getta, che verrà scartato dopo la chiamata del metodo.