どのデザインパターンがこの問題の解決に役立つかはわかりません。
使用するWorkerクラスを決定する「コーディネーター」クラスがあります-存在するすべての種類のWorkerについて知る必要はありませんが、WorkerFactoryを呼び出し、共通のIWorkerインターフェイスに基づいて動作します。
次に、適切なWorkerを動作するように設定し、 'DoWork'メソッドの結果を返します。
これまでは順調でした...今までは。新しいワーカークラス「WorkerB」の新しい要件があります。これは、作業を行うために追加の情報、つまり追加の入力パラメーターを必要とします。
余分な入力パラメーターを使用してオーバーロードされたDoWorkメソッドが必要なようですが、既存のすべてのワーカーはそのメソッドを実装する必要があります。これらのワーカーは本当にそのメソッドを必要としないので間違っているようです。
これをリファクタリングして、どのワーカーが使用されているかをコーディネーターに認識させずに、各ワーカーがジョブを実行するために必要な情報を取得できるようにしますが、不要な作業はワーカーに行わせませんか?
既に多くの既存のワーカーがいます。
新しいWorkerBクラスの要件に対応するために、既存の具象ワーカーを変更する必要はありません。
ここではデコレータパターンが良いと思うかもしれませんが、デコレータが同じメソッドでオブジェクトを異なるパラメータで装飾するのを見たことはありません...
コードの状況:
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
その追加のパラメーターをそのGetWorkerResult
機能に対応させるために、すでに変更する必要がありました-つまり、SOLIDのOpen-Closed-Principleに違反しています。その結果、すべてのコード呼び出しCoordinator.GetWorkerResult
も変更する必要がありました。その関数を呼び出す場所を見てください:どのIWorkerを要求するかをどのように決定しますか?それはより良い解決策につながる可能性があります。
IWorker
インタフェースは、古いバージョンを記載されている、またはことは、追加パラメータを使用して新しいバージョンですか?