Non sono sicuro di quale modello di progettazione potrebbe aiutarmi a risolvere questo problema.
Ho una classe, 'Coordinatore', che determina quale classe di lavoro dovrebbe essere usata - senza dover conoscere tutti i diversi tipi di lavoratori che ci sono - chiama semplicemente una WorkerFactory e agisce sulla comune interfaccia di IWorker.
Quindi imposta il lavoratore appropriato affinché funzioni e restituisce il risultato del suo metodo "DoWork".
Questo è andato bene ... fino ad ora; abbiamo un nuovo requisito per una nuova classe Worker, "WorkerB", che richiede una quantità aggiuntiva di informazioni, ad esempio un parametro di input aggiuntivo, affinché funzioni.
È come se avessimo bisogno di un metodo DoWork sovraccarico con il parametro di input aggiuntivo ... ma poi tutti i Worker esistenti dovrebbero implementare quel metodo - il che sembra sbagliato dato che quei Worker non hanno davvero bisogno di quel metodo.
Come posso fare un refactoring per mantenere il Coordinatore ignaro di quale Lavoratore viene utilizzato e consentire comunque a ciascun Lavoratore di ottenere le informazioni necessarie per svolgere il proprio lavoro, ma senza che un Lavoratore faccia ciò che non è necessario?
Ci sono già molti lavoratori esistenti.
Non voglio cambiare nessuno dei lavoratori concreti esistenti per soddisfare i requisiti della nuova classe WorkerB.
Ho pensato che forse un motivo Decoratore sarebbe stato buono qui, ma non ho visto nessun Decoratore decorare un oggetto con lo stesso metodo ma parametri diversi prima ...
Situazione nel codice:
public class Coordinator
{
public string GetWorkerResult(string workerName, int a, List<int> b, string c)
{
var workerFactor = new WorkerFactory();
var worker = workerFactor.GetWorker(workerName);
if(worker!=null)
return worker.DoWork(a, b);
else
return string.Empty;
}
}
public class WorkerFactory
{
public IWorker GetWorker(string workerName)
{
switch (workerName)
{
case "WorkerA":
return new ConcreteWorkerA();
case "WorkerB":
return new ConcreteWorkerB();
default:
return null;
}
}
}
public interface IWorker
{
string DoWork(int a, List<int> b);
}
public class ConcreteWorkerA : IWorker
{
public string DoWork(int a, List<int> b)
{
// does the required work
return "some A worker result";
}
}
public class ConcreteWorkerB : IWorker
{
public string DoWork(int a, List<int> b, string c)
{
// does some different work based on the value of 'c'
return "some B worker result";
}
public string DoWork(int a, List<int> b)
{
// this method isn't really relevant to WorkerB as it is missing variable 'c'
return "some B worker result";
}
}
Coordinator
doveva già essere modificato per accogliere quel parametro aggiuntivo nella sua GetWorkerResult
funzione - ciò significa che il principio aperto-chiuso di SOLID è stato violato. Di conseguenza, è Coordinator.GetWorkerResult
stato necessario modificare anche tutte le chiamate in codice . Quindi guarda il luogo in cui chiami quella funzione: come decidi quale IWorker richiedere? Ciò può portare a una soluzione migliore.
IWorker
interfaccia è elencata nella versione precedente o è una nuova versione con un parametro aggiunto?