Sono in procinto di refactoring una porzione piuttosto grande di codice spaghetti. In poche parole è una grande classe "divina" che si dirama in due processi diversi a seconda delle condizioni. Entrambi i processi sono lunghi e hanno un sacco di codice duplicato.È una buona opzione di progettazione per chiamare un metodo di inizializzazione di classe all'interno di una fabbrica prima di iniettarlo
Quindi il mio primo sforzo è stato quello di estrarre questi due processi nelle proprie classi e inserire il codice comune in un genitore da cui entrambi ereditano.
Sembra qualcosa di simile a questo:
public class ExportProcess
{
public ExportClass(IExportDataProvider dataProvider, IExporterFactory exporterFactory)
{
_dataProvider = dataProvider;
_exporterFactory = exporterFactory;
}
public void DoExport(SomeDataStructure someDataStructure)
{
_dataProvider.Load(someDataStructure.Id);
var exporter = _exporterFactory.Create(_dataProvider, someDataStructure);
exporter.Export();
}
}
io sono un avido lettore del blog di Mark Seemann e in this entry spiega che questo codice ha un odore di accoppiamento temporale dal momento che è necessario chiamare il metodo Load sul fornitore di dati prima che sia in uno stato utilizzabile.
Sulla base di questo, e dal momento che l'oggetto viene iniettato a quelli restituiti dalla fabbrica in ogni caso, sto pensando di cambiare la fabbrica per fare questo:
public IExporter Create(IExportDataProvider dataProvider, SomeDataStructure someDataStructure)
{
dataProvider.Load(someDataStructure.Id);
if(dataProvider.IsNewExport)
{
return new NewExportExporter(dataProvider, someDataStructure);
}
return new UpdateExportExporter(dataProvider, someDataStructure);
}
a causa del nome "DataProvider" si probabilmente ho indovinato che il metodo Load sta effettivamente facendo un accesso al database.
Qualcosa mi dice che un oggetto che fa un accesso al database all'interno del metodo di creazione di una fabbrica astratta non è un buon progetto.
Ci sono linee guida, buone pratiche o qualcosa che dice che questa è effettivamente una cattiva idea?
Grazie per il vostro aiuto.
Ovviamente dataProvider.Load ha un qualche tipo di effetto collaterale, lungo le linee di recupero un'istanza di qualcosa in una proprietà? Il resto del metodo factory usa effettivamente 'dataProvider' e' someDataStructure'? In caso contrario, i tuoi argomenti al metodo factory dovrebbero essere refactored per accettare gli argomenti di cui ha realmente bisogno. – PatrikAkerstrand
@PatrikAkerstrand: buon punto Patrik. Gli oggetti creati dalla fabbrica, infatti, utilizzano pesantemente il fornitore di dati poiché il suo metodo Load popola alcune proprietà necessarie. Questo è un primo sforzo di refactoring ma, sfortunatamente, questo è un debito tecnico che potrebbe non essere pagato nel breve periodo. –
ok, considera questo: Se dataProvider.Load verrebbe chiamato più volte, creerebbe qualche problema? ** Se no **: Cool, sposterei la chiamata 'Load' nel metodo factory in quanto semplificherebbe i client (tutte le chiamate a .Load rientrerebbero nel metodo factory). ** Se sì **: Non hai altra scelta che tenerlo fuori dalla fabbrica, dal momento che non puoi sapere se è inizializzato o no – PatrikAkerstrand