Sto tentando di ridefinire quello che sta diventando un metodo molto grande - attualmente circa 350 linee - che contiene un alto grado di complessità ciclomatica .
Capisco e attribuisco alle teorie che i metodi dovrebbero essere brevi e che le preoccupazioni dovrebbero essere separate, e ho letto cose come this e questo tra gli altri. Sto lottando per rifattorizzare il mio metodo, però, per un paio di ragioni. Per aiutare a illustrare questi, prima ecco un esempio semplificato di come appare il metodo prima del refactoring:
private static void ProcessMessage(Message toProcess)
{
var processingIssues = new StringBuilder();
var transformedAttachments = new List<TransformedAttachmentData>();
foreach (var attach in toProcess.Attachments)
{
//in reality there is quite a bit of nested logic here,
//but I'll represent it as a single if-else block.
if (true)
{
//in reality, a third-party library is used in multiple
//levels of this logic hierarchy to produce the transformed data.
transformedAttachments.Add(new TransformedAttachmentData(attach));
}
else
{
processingIssues.AppendLine(
string.Format(@"Issue ""{0}"" occurred with " +
@"attachment ""{1}"".", "blah blah problem", attach.Name));
}
}
/*
* do something else complex here with
* processingIssues and validResults
*/
}
In primo luogo, la complessità ciclomatica che mi riguarda è nata da un complesso insieme di regole aziendali che devono essere applicate che insieme riassumono un paio di insiemi di dati condivisi (qui rappresentati come processingIssues
e transformedAttachments
). Fondamentalmente ciò che questo significa per me è che non solo devo rompere il foreach
out nel suo metodo, ma dovrei anche considerare di rompere l'albero logico contenuto in esso in metodi aggiuntivi nell'interesse di mantenere i miei metodi "brevi". In altre parole, sembrerebbe che non sia abbastanza solo per rompere il mio metodo attuale nelle sue due parti esterne più ovvie: "pre-elaborazione" e "post-elaborazione" degli allegati, se vuoi. Quanto lontano devo andare con questo dato che mi sto occupando di un albero logico complicato con preoccupazioni che non sono così "separate" l'una dall'altra. In altre parole, se "la separazione delle preoccupazioni" è una ragione per il refactoring di metodi più piccoli, ma lo è anche per la "complessità ciclomatica" - che sembrano entrambi concetti ortogonali - che è la ragione "giusta" per il refactoring, e come dovrei farlo nel secondo caso?
In secondo luogo, al fine di separare alcune delle preoccupazioni per separare i metodi, quei metodi separati dovranno restituire più variabili (di nuovo, processingIssues
e transformedAttachments
), entrambi sono solo necessari all'interno dei metodi separati stessi , quindi mi trovo di fronte alla scelta: utilizzare i parametri di output o creare una piccola classe per racchiudere i valori restituiti. Quale è meglio?
Qualche consiglio su questo argomento e sui miei specifici hang-up sarebbe molto apprezzato.