2017-09-01 4 views
0

明確にする:enumを使用する代わりに、どのメソッドを使用するかをenumが指示するところで、私は同じベースクラスからデリバリするクラスを使用しています。したがって、enumを使用してメソッドを選択する代わりに、ユーザーは(ドロップダウンインターフェイスを介して)使用したいクラスを選択し、そのクラスには呼び出されるメソッドのオーバーライドが含まれます。下に示すように動作させた後、私はそれを正しくやっているかどうかをオンラインで見てみました。それは多くの問題を解決する方法ですが、私の問題はそれを記述するための用語を知らず、将来深刻な問題を引き起こすかどうかを確認することです。クラスセレクタを実装する最良の方法

私が使用したいツールを選択するにはEnumsを使用する前に(enum tool {brush、eraser、drag})。しかし、Enumを使用する代わりにすべてを効率的にするために、基本的なクラス "ToolType"から派生する各ツールのクラスを作成します。次に、リフレクションを使用して、ToolTypeを継承して静的配列に配置するすべてのクラスを見つけます。そして今、私はプロジェクトのほとんどのものにこのメソッドを使用しています。新しいクラスを追加するたびにenum配列を編集する必要はなく、追加/削除が簡単です。モジュラープロジェクトの最善の解決策だと感じていますが、これの例はまだ見つかっていないので、正しい方法で実行しているかどうかはわかりません。私は何を探していますか?

static Family() { 
    List<Type> allTypes = CsharpFuncs.GetAllChildTypesOf<T>(); 

    family = new T[allTypes.Count]; 
    names = new string[allTypes.Count]; 

    Debug.Log("Creating "+typeof(T).ToString()); 

    for (int i = 0; i < allTypes.Count; i++) { 
     Debug.Log("Adding " + allTypes[i].ToString()); 
     T tmp = (T)Activator.CreateInstance(allTypes[i]); 
     family[i] = tmp; 
     tmp.index = i; 
     names[i] = tmp.ToString(); 
    } 
} 

これは、その後、私は

public class newToolBase : Family<newToolBase> { 

}

パブリッククラス消しゴム有することができる

public class Family<T> where T : Family<T> 

のコンストラクタである:newToolBase {

を}

パブリッククラス鉛筆:newToolBase私はUnityと私が「選択」の意味を使用しています{

}

は、手動でドロップダウンから何かを選択するための通常のオプションです。あなたが見るように、基本クラスは名前の配列を持ち、ユーザーが何かを選択しているときに表示されます。スポーン可能なすべてのオブジェクト、すべてのAIメソッドはこのクラスを使用します。私は基本クラスから派生したスクリプトを追加します。これはファミリクラスからデリバリされ、リストで選択または追加できます。

以下のコメントから、私はDependencies Injectionについて知り、現在それについて読んでいます。私はこれを書いて、人々がすぐに私がしようとしていることを認識し、このようなものを指し示すことを期待しています。

明確にするために、私のアプローチには明らかな問題はありませんが、多くの列挙をこれに置き換える時間を費やす前に、私は確信しています。ありがとう。

+4

1あなたは、任意の依存性注入を使用していますか?例えば。 「Unity」、「MEF」、「Ninject」 – Nova

+0

禁忌:2番目のツールタイプが必要な場合はどうなりますか?あなたが選択したくないもの、最初のセットは... – Fildor

+0

あなたは[パターン](http://www.dofactory.com/net/design-patterns)を求めているようですあなたは何が問題なのかを示さなかった。セレクタ?何によって?キー辞書による、インデックスコレクションによる...また、現在の方法が悪い理由の基準は何ですか?疑いだけ?誰もが地獄に行くように教えてください、あなたはプログラマーです、それはあなたの仕事です... – Sinatr

答えて

1

私はあなたができることを考えています。これを行うにはおそらくより良い方法がありますが、うまくいけば、私はあなたに方向性を促すことができます。マネージド拡張フレームワークのための

MEFスタンド -

マネージド拡張フレームワークやMEFは、軽量、拡張可能なアプリケーションを作成するためのライブラリです。この設定を取得するために MEF

はあなたのプロジェクトにSystem.ComponentModel.Compositionライブラリを追加する必要があり、非常に単純です。

私はあなたのユースケースを示すためにコンソールアプリケーションを使用しました。最初に、MEFコンテナを初期化する必要があります。

class MefContainer 
{ 
    public CompositionContainer Container { get; } 

    public MefContainer() 
    { 
     var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); // You can use an AggregateCatalog if you have more than one assembly. 

     Container = new CompositionContainer(catalog); 

     Container.ComposeParts(this); 
    } 
} 

コンテナクラスをセットアップしたので、ツールクラスをセットアップする必要があります。私はあなたが上記の例から外挿し、自分の独自のロジックを適用できると仮定

class Program 
{ 
    public static List<ToolType> ToolTypes { get; set; } 

    static void Main(string[] args) 
    { 
     var mefContainer = new MefContainer(); 

     ToolTypes = mefContainer.Container.GetExportedValues<ToolType>().ToList(); 

     ToolTypes.First(x => x.GetType() == typeof(Brush))?.Test(); 
     ToolTypes.First(x => x.GetType() == typeof(Eraser))?.Test(); 
     ToolTypes.First(x => x.GetType() == typeof(Drag))?.Test(); 
    } 
} 

abstract class ToolType // I've used an abstract class here, but you can use interfaces or normal classes. 
{ 
    public virtual void Test() 
    { 
     Console.WriteLine("Base"); 
    } 
} 

[Export(typeof(ToolType)), PartCreationPolicy(CreationPolicy.NonShared)] // Part creation policy is for your lifetime management. NonShared is instanced and Shared would be like a singleton. 
class Brush : ToolType 
{ 
    public override void Test() 
    { 
     Console.WriteLine("Brush"); 
    } 
} 

[Export(typeof(ToolType)), PartCreationPolicy(CreationPolicy.NonShared)] 
class Eraser : ToolType 
{ 
    public override void Test() 
    { 
     Console.WriteLine("Eraser"); 
    } 
} 

[Export(typeof(ToolType)), PartCreationPolicy(CreationPolicy.NonShared)] 
class Drag : ToolType 
{ 
    public override void Test() 
    { 
     Console.WriteLine("Drag"); 
    } 
} 

は、今では、コンソールアプリケーションでの使用です。 上記はコンソールアプリケーションに貼り付けるだけで動作するはずです。正しい参照を追加することを忘れないでください。

これは、保守性と拡張性に役立つ非常にモジュラーなアプリケーションを作成するのに役立ちます。 他の依存性注入の選択肢があります。必要なものに依存します。

これが役に立ちます。

追加:これをさらに拡張するには、MEFコンテナをプロジェクト全体で使用するために1回だけ初期化する必要があります。 私はToolTypes = mefContainer.Container.GetExportedValues<ToolType>().ToList(); を使用しかし、あなたは

[ImportMany(typeof(ToolType))] 
public List<ToolType> ToolTypes { get; set; } 

を使用することができますかのみが存在する場合

[Import(typeof(ToolType))] 
public ToolType Tool { get; set; } 
関連する問題