Nie jestem pewien, który wzór może pomóc mi rozwiązać ten problem.
Mam klasę „Koordynator”, która określa, która klasa Worker powinna zostać użyta - bez konieczności znajomości wszystkich różnych rodzajów Workerów - po prostu wywołuje WorkerFactory i działa na wspólnym interfejsie IWorker.
Następnie ustawia odpowiedniego Workera do pracy i zwraca wynik metody „DoWork”.
Było dobrze ... do tej pory; mamy nowy wymóg dotyczący nowej klasy Worker, „WorkerB”, która wymaga dodatkowej ilości informacji, tj. dodatkowego parametru wejściowego, aby mógł on wykonać swoją pracę.
To tak, jakbyśmy potrzebowali przeciążonej metody DoWork z dodatkowym parametrem wejściowym ... ale wtedy wszyscy istniejący pracownicy musieliby zaimplementować tę metodę - co wydaje się błędne, ponieważ ci pracownicy naprawdę nie potrzebują tej metody.
Jak mogę to zmienić, aby Koordynator nie był świadomy, z którego Pracownika korzysta, a jednocześnie pozwalał każdemu Pracownikowi na uzyskanie informacji potrzebnych mu do wykonywania swojej pracy, ale nie pozwalał, aby Żaden Pracownik robił rzeczy, których nie potrzebuje?
Istnieje już wielu pracowników.
Nie chcę zmieniać żadnego z istniejących konkretnych Workerów, aby dostosować je do wymagań nowej klasy WorkerB.
Myślałem, że być może wzór Dekoratora byłby tutaj dobry, ale nie widziałem żadnych Dekoratorów dekorujących obiekt tą samą metodą, ale o różnych parametrach przed ...
Sytuacja w kodzie:
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";
}
}
Coordinatorjuż musiał zostać zmieniony, aby uwzględnić ten dodatkowy parametr w swojej GetWorkerResultfunkcji - oznacza to, że naruszono zasadę otwartego-zamkniętego SOLID. W rezultacie wszystkie wywołania kodu również Coordinator.GetWorkerResultmusiały zostać zmienione. Spójrz więc na miejsce, w którym wywołujesz tę funkcję: w jaki sposób decydujesz, którego IWorkera poprosić? Może to prowadzić do lepszego rozwiązania.
IWorkerinterfejs zawiera starą wersję, czy jest to nowa wersja z dodanym parametrem?