私のプログラムには 2 つのクラスがあります。どちらも同じ基本クラスから派生します。
class A : MyBase
{
internal A(InitVal initVal)
}
class B : MyBase
{
internal B(InitVal initVal)
}
InitVal
コンストラクターを介して注入される別のクラスです。このクラスは内部使用用です。内部コンストラクターのため、ユーザーはクラスのインスタンスを直接作成できませA
んB
。代わりに、これらのオブジェクトを作成するメソッドを作成しました。
class Initiator
{
InitVal initVal;
public T CreateObject<T>(ObjectInstance objectInstance) where T : MyBase
{
MyBase myBase = null;
switch(objectInstance)
{
case ObjectInstance.A:
myBase = new A(initVal);
break;
case ObjectInstance.B:
myBase = new B(initVal);
break;
}
return (T)myBase;
}
...
}
ObjectInstance
上記のコードの列挙型です。
これは問題なく動作しますが、これほど醜いコードを見たことがないはずです。
使用すべき作成パターンを提案してください。ObjectInstance
機能を変更せずに列挙型を削除したい。大掃除になります。
dotfactoryに記載されているCreational Patternsを試しました。
この場合、適切に見えません。Factory Method
Abstract Factory
私のコードは醜く見えますが、読んで理解するのはとても簡単です。コードの複雑さを増す上記のパターンを実装してみました。したがって、これは回答を選択する際の私の基準でもあります。
Initiator
クラス以外のコードを変更することはできません。他のすべてのクラスには、編集のためにアクセスできません。
編集 1: 上記のコードが私の見解では醜い理由
1) メソッドの呼び出し中CreateObject
に、ユーザーはオブジェクトのタイプを 2 回指定する必要があります。
A a = initiator.CreateObject<A>(ObjectInstance.A);
最初はT
ジェネリック値、2 番目は列挙値です。これは避けたい。
2) ユーザーはオブジェクトのタイプを 2 回指定する必要があるため、間違える可能性があります。
A a = initiator.CreateObject<A>(ObjectInstance.B);
上記のコードでは、列挙値とジェネリック値が異なります。これは許可されておらず、問題になります。私のコードでは、これを避けることはできません。
それが理由です; 複雑さを増すことなく、自分のケースに合ったパターンを探しています。
どうにかして enum の必要性を取り除けば、コードはずっと良くなります。の署名を次のように変更できればCreateObject
、ずっと良くなります。
public T CreateObject<T>() where T : MyBase
しかし、このメソッドを実装して適切なインスタンスを作成する方法がわかりません。