さまざまなアルゴリズムを実装するさまざまなエンジンがたくさんあります。それらはすべて同じインターフェースを実装していますが、構成メソッドが異なります。それらのほとんどはパラメーターなしで構成され、そのうちのいくつかは 1 つの整数で構成され、2 つの整数で構成されるものはさらに少なくなります。将来、整数が 3 つまたは 4 つになる可能性はわずかです。
エンジンをいつ開始または停止する必要があるかを決定するエンジン コントローラーを作成する必要があります。これは、すべてのエンジンに共通することです。私が考えたオプションは次のとおりです。
- 利用可能な最大のConfigureメソッドと同じ数のパラメーターを持つ一意のインターフェイスを作成し、エンジンで不要なものを無視します。このようにして、EngineController は 1 つだけになります。
- さまざまな構成メソッドごとにインターフェイスを作成し、さまざまなインターフェイスごとに EngineController を作成します (ただし、これにより、パラメーターの数だけが異なる多くのクラスが作成され、新しいクラスを作成するたびに 2 つの新しいクラスが必要になります)。パラメータがエンジンに追加されます。
- ...
不要なパラメーターを渡すのは「醜い」ように見え、2番目のオプションで生成されるクラスの数が多いため(非常に小さな違いしかないため)、2つのソリューションのいずれにも満足していません。
この問題を回避する設計またはパターンはありますか?
編集(回答ありがとうございます。この編集はそれらすべてに回答し、質問を明確にします):
例を挙げると、これらはエンジンです。
abstract class EngineBase
{
public void Start() {...}
public void Stop() {...}
}
class EngineOne : EngineBase
{
public void Configure(int parameter1) {...};
}
class EngineTwo : EngineBase
{
public void Configure(int parameter1, int parameter2) {...};
}
class EngineThree : EngineBase
{
public void Configure(int parameter1, int parameter2, int parameter3) {...};
}
すべてのエンジンは、いつ開始または終了するかを決定する同じロジックを持っているため、EngineController と呼ばれる、それらを処理する新しいクラスを作成したいと考えています。コントローラーは、必要に応じて、Configure、Start、および Stop を呼び出します。
class EngineController
{
EngineBase _engine; ??? or what?
void SuperviseEngine() { ... _engine.Configure(x,x,...) ... _engine.Start() ...
}
最初のアイデアは、EngineBase クラスに次のメソッドを追加することです。
abstract class EngineBase
{
public void Start() {...}
public void Stop() {...}
public void Configure(int parameter1, int parameter2, int parameter3) {...}
}
class EngineController
{
EngineBase _engine;
void SuperviseEngine() { ... _engine.Configure(x,y,z) ... _engine.Start() ...
}
不要なパラメータを無視しますが、私はその考えが好きではありません。それから私は次のことをすることを考えました:
interface I1ParameterConfigurable
{
public void Configure(int parameter1) {...};
}
interface I2ParameterConfigurable
{
public void Configure(int parameter1, int parameter2) {...};
}
interface I3ParameterConfigurable
{
public void Configure(int parameter1, int parameter2, int parameter3) {...};
}
次に、エンジンの種類ごとに 3 つの異なるコントローラーを作成します。
class EngineController1Parameter
{
EngineBase _engine;
I1ParameterConfigurable _configurableEngine = _engine as I1ParameterConfigurable;
void SuperviseEngine() { ... _configurableEngine .Configure(x) ... _engine.Start()
}
class EngineController2Parameter
{
EngineBase _engine;
I2ParameterConfigurable _configurableEngine = _engine as I2ParameterConfigurable;
void SuperviseEngine() { ... _configurableEngine .Configure(x, y) ... _engine.Start()
}
アイデアはわかりますが、これを回避する方法がある場合、これにより多くのインターフェイス/クラスが作成されると思います。
あなたの答えのおかげで、最初のオプションに似ていますが、配列(またはIEnumerableなど)を使用して未定義の数のパラメーターを渡す3番目のオプションがあります。アイデアは悪くありませんが、パラメーター名が失われます。しかし、おそらくそれは今までの最良の選択肢です。