Je ne sais pas quel modèle de conception pourrait m'aider à résoudre ce problème.
J'ai une classe, 'Coordinator', qui détermine quelle classe Worker doit être utilisée - sans avoir à connaître tous les différents types de travailleurs qu'il y a - elle appelle simplement une WorkerFactory et agit sur l'interface IWorker commune.
Il définit ensuite le Worker approprié pour fonctionner et renvoie le résultat de sa méthode «DoWork».
Cela s'est bien passé ... jusqu'à maintenant; nous avons une nouvelle exigence pour une nouvelle classe Worker, "WorkerB" qui nécessite une quantité supplémentaire d'informations, c'est-à-dire un paramètre d'entrée supplémentaire, pour qu'elle puisse faire son travail.
C'est comme si nous avions besoin d'une méthode DoWork surchargée avec le paramètre d'entrée supplémentaire ... mais alors tous les Workers existants devraient implémenter cette méthode - ce qui semble faux car ces Workers n'ont vraiment pas besoin de cette méthode.
Comment puis-je refactoriser cela pour que le coordinateur ne sache pas quel travailleur est utilisé et qu'il permette toujours à chaque travailleur d'obtenir les informations dont il a besoin pour faire son travail mais qu'aucun travailleur ne fasse les choses dont il n'a pas besoin?
Il y a déjà beaucoup de travailleurs existants.
Je ne veux pas avoir à changer l'un des travailleurs en béton existants pour répondre aux exigences de la nouvelle classe WorkerB.
Je pensais que peut-être un motif de décorateur serait bien ici, mais je n'ai vu aucun décorateur décorer un objet avec la même méthode mais des paramètres différents auparavant ...
Situation dans le code:
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
a déjà dû être modifié pour tenir compte de ce paramètre supplémentaire dans sa GetWorkerResult
fonction - cela signifie que le principe ouvert-fermé de SOLID est violé. En conséquence, tous les appels de code Coordinator.GetWorkerResult
devaient également être modifiés. Regardez donc l'endroit où vous appelez cette fonction: comment décidez-vous quel IWorker demander? Cela pourrait conduire à une meilleure solution.
IWorker
interface est-elle répertoriée dans l'ancienne version ou s'agit-il d'une nouvelle version avec un paramètre ajouté?