0

私が開発しているアプリケーションでは、状況に直面しています。このための設計パターンがあるかどうか知りたいです。以下の通りです

  1. ユーザーは、プロセスのさまざまなアルゴリズムを使用して Web インターフェイスに表示されます
  2. ユーザーの選択はデータベースに保存されます。
  3. ここで、アプリケーションは、選択したアルゴリズムに応じて異なる方法で計算を実行する必要があります。

これを実装するための良い戦略は何ですか? 今、私たちがやっていることは -

  1. コード内のすべてのアルゴリズム タイプと対応するクラス名を含む参照 DB テーブルを用意します (たとえば、クイック ソート アルゴリズムの場合、QuickSort を格納します)。これは、新しいアルゴリズムが登場するたびに手動で更新する必要があります
  2. コードでは、アルゴリズム タイプを取得し、リフレクションを使用して適切なアルゴリズム タイプをインスタンス化します。C# では、以下のようなコードを使用します

    System.Reflection.Assembly 型 = System.Reflection.Assembly.LoadFile(System.Reflection.Assembly.GetExecutingAssembly().Location.ToString());
    foreach (type t in types) if (t.Name==classname) createinstanceof(t) //classnames は、DB の参照テーブルからロードされるすべてのクラス タイプのリストです。

私の直感では、これは非常に標準的な問題のように見えるため、これを行うためのより簡単でより良い方法があるはずです。私は戦略パターンを知っていますが、私が望むのは、単純化して、できれば手動タスクを削除することです。

4

3 に答える 3

2

Interface + Reflection を使用して、データベースにアルゴリズム名を保存しないようにすることができます。

インターフェイス IMySortingAlgorithms を次のように作成します。

public interface IMySortingAlgorithms
    {
        string Name { get; }
        string[] Sort(string[] input);
    }

次に、リフレクションを使用してソート アルゴリズムを取得する Factory を作成します。

public static class MyAlgoFactory
{
    private static Dictionary<string, IMySortingAlgorithms> m_dict;

    /// <summary>
    /// For all the assmeblies in the current application domain,
    /// Get me the object of all the Types that implement IMySortingAlgorithms
    /// </summary>
    static MyAlgoFactory()
    {
        var type = typeof(IMySortingAlgorithms);
        m_dict = AppDomain.CurrentDomain.GetAssemblies().
            SelectMany(s => s.GetTypes()).
            Where(p => {return type.IsAssignableFrom(p) && p != type;}).
            Select(t=> Activator.CreateInstance(t) as IMySortingAlgorithms).
            ToDictionary(i=> i.Name);
    }

    public static IMySortingAlgorithms GetSortingAlgo(string name)
    {
        return m_dict[name];
    }
}

すべてのソート アルゴリズムがこのインターフェイスを実装できるようになりました。

 public class MySortingAlgo1 : IMySortingAlgorithms
    {
        #region IMySortingAlgorithms Members

        public string Name
        {
            get { return "MySortingAlgo1"; }
        }

        public string[] Sort(string[] input)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

この方法では、ソート用の新しいクラスを作成するたびに、クラス名をデータベースに追加する必要がありません。

以下は、MyAlgoFactory の非 Linq バージョンです。

    /// <summary>
    /// For all the assmeblies in the current application domain,
    /// Get me the object of all the Types that implement IMySortingAlgorithms
    /// </summary>
   static MyAlgoFactory()
        {
            m_dict = new Dictionary<string, IMySortingAlgorithms>();
            var type = typeof(IMySortingAlgorithms);
            foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (Type p in asm.GetTypes())
                {
                    if (type.IsAssignableFrom(p) && p != type)
                    {
                        IMySortingAlgorithms algo = Activator.CreateInstance(p)
                              as IMySortingAlgorithms;
                        m_dict[algo.Name] = algo;
                    }
                }
            }
        }
于 2009-07-25T06:59:56.787 に答える
2

そうです、あなたが望むのはStrategyパターンです。ただし、実際にやりたいことは、各アルゴリズムが使用するインターフェイスを定義することです。これにより、アルゴリズムのパラメーターを指定でき、インターフェイスを介して簡単に各パラメーターを呼び出すことができます。見苦しいリフレクション プロセスではありません。質問に記述します。

于 2009-07-24T22:31:24.000 に答える
0

Factory デザインと Strategy デザインを次のように使用します。

public interface ISorter {
   // Prototype for your sort function goes here
}

public class QuickSorter implements ISorter {}

public class SorterFactory {
   public ISorter getSorter( string sortType ) {
      // Return the correct type of sorting algorithm
      if ( sortType.equals( "QuickSort" ) ) {
         return new QuickSorter();
      }
   }
}

次に、ユーザーがデータベースで選択したものを検索し、それをパラメータとしてファクトリに渡します。

MOD への注意: 正しい構文がわからない場合は、Java コードを編集しないでください。これが C# だと思わない限り、どちらでもかまいません。

于 2009-07-24T22:40:41.360 に答える