Não tenho certeza de qual padrão de design pode me ajudar a resolver esse problema.
Eu tenho uma classe, 'Coordinator', que determina qual classe Worker deve ser usada - sem ter que saber sobre todos os diferentes tipos de Workers que existem - ela apenas chama um WorkerFactory e atua na interface comum do IWorker.
Em seguida, define o Worker apropriado para trabalhar e retorna o resultado do método 'DoWork'.
Isso tem sido bom ... até agora; temos um novo requisito para uma nova classe Worker, "WorkerB", que requer uma quantidade adicional de informações, isto é, um parâmetro de entrada adicional, para que ele faça seu trabalho.
É como se precisássemos de um método DoWork sobrecarregado com o parâmetro de entrada extra ... mas todos os Trabalhadores existentes teriam que implementar esse método - o que parece errado, pois esses Trabalhadores realmente não precisam desse método.
Como posso refatorar isso para manter o coordenador inconsciente de qual trabalhador está sendo usado e ainda permitir que cada trabalhador obtenha as informações necessárias para realizar seu trabalho, mas que nenhum trabalhador faça o que não é necessário?
Já existem muitos Trabalhadores.
Não quero alterar nenhum dos Trabalhadores concretos existentes para acomodar os requisitos da nova classe WorkerB.
Eu pensei que talvez um padrão Decorator seria bom aqui, mas eu não vi nenhum Decorator decorar um objeto com o mesmo método, mas com parâmetros diferentes antes ...
Situação no 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";
}
}
Coordinator
já tinha que ser alterado para acomodar esse parâmetro extra em sua GetWorkerResult
função - isso significa que o princípio de aberto-fechado do SOLID é violado. Como conseqüência, todas as chamadas de código também Coordinator.GetWorkerResult
precisavam ser alteradas. Portanto, observe o local em que você chama essa função: como você decide qual IWorker solicitar? Isso pode levar a uma solução melhor.
IWorker
interface está listada na versão antiga ou é uma nova versão com um parâmetro adicionado?