No estoy seguro de qué patrón de diseño podría ayudarme a resolver este problema.
Tengo una clase, 'Coordinador', que determina qué clase de Trabajador se debe usar, sin tener que conocer todos los diferentes tipos de Trabajadores que hay, simplemente llama a WorkerFactory y actúa sobre la interfaz común de IWorker.
Luego establece el Trabajador apropiado para trabajar y devuelve el resultado de su método 'DoWork'.
Esto ha estado bien ... hasta ahora; tenemos un nuevo requisito para una nueva clase de Trabajador, "WorkerB", que requiere una cantidad adicional de información, es decir, un parámetro de entrada adicional, para que pueda hacer su trabajo.
Es como si necesitáramos un método DoWork sobrecargado con el parámetro de entrada adicional ... pero todos los trabajadores existentes tendrían que implementar ese método, lo que parece incorrecto ya que esos trabajadores realmente no necesitan ese método.
¿Cómo puedo refactorizar esto para mantener al Coordinador al tanto de qué Trabajador se está utilizando y aún así permitir que cada Trabajador obtenga la información que necesita para hacer su trabajo pero que ningún Trabajador haga cosas que no necesita?
Ya hay muchos trabajadores existentes.
No quiero tener que cambiar ninguno de los Trabajadores concretos existentes para acomodar los requisitos de la nueva clase WorkerB.
Pensé que tal vez un patrón Decorador sería bueno aquí, pero no he visto ningún Decorador decorar un objeto con el mismo método pero con diferentes parámetros antes ...
Situación en el código:
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";
}
}
Coordinatorya tuvo que cambiarse para acomodar ese parámetro adicional en su GetWorkerResultfunción, eso significa que se viola el Principio de Cerrado Abierto de SOLID. Como consecuencia, todas las llamadas de código Coordinator.GetWorkerResulttuvieron que ser cambiadas también. Mire el lugar donde llama a esa función: ¿cómo decide qué IWorker solicitar? Eso puede conducir a una mejor solución.
IWorkerinterfaz muestra la versión anterior o es una nueva versión con un parámetro agregado?