针对不同输入的不同算法

时间:2009-07-24 22:21:47

标签: c# design-patterns strategy-pattern

在我正在开发的应用程序中,我面临着一种情况;我想知道是否有这样的设计模式。它如下

  1. 用户在Web界面上显示,具有不同的流程算法
  2. 用户选择存储在数据库中。
  3. 现在,应用程序应根据所选算法执行不同的计算。
  4. 实施此策略的好策略是什么?现在我们正在做的是 -

    1. 有一个参考数据库表,其中包含所有算法类型和代码中相应的类名(例如,如果快速排序算法,那么我们存储QuickSort)。每次出现新算法时都必须手动更新
    2. 在代码中,获取算法类型并使用反射来实例化适当的算法类型。在C#中,我们使用类似于下面的代码

      System.Reflection.Assembly types = System.Reflection.Assembly.LoadFile(System.Reflection.Assembly.GetExecutingAssembly()。Location.ToString());
      foreach(类型中的类型t)  if(t.Name == classname)     createinstanceof(t)的 // classnames是从DB中的引用表加载的所有类类型的列表。

    3. 我的直觉是应该有一个更简单/更好的方法来做到这一点,因为它似乎是一个非常标准的问题。我知道strategy pattern - 但我想要的是简化并可能删除手动任务。

3 个答案:

答案 0 :(得分:2)

是的,你是对的,你想要的是Strategy模式。但是,您真正想要做的是定义一个接口,您的每个算法都使用该接口,允许您指定算法的参数,并允许您通过界面简单地调用每个参数,而不是丑陋的反射过程。在问题中描述。

答案 1 :(得分:2)

您可以使用Interface + Reflection来避免在数据库中存储算法名称。

创建接口IMySortingAlgorithms as,

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

现在,编写一个使用反射来获取排序算法的工厂。

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
    }

这样,无论何时创建新的排序类,都不需要将类名添加到数据库中。

以下是My Lingo版本的MyAlgoFactory

    /// <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;
                    }
                }
            }
        }

答案 2 :(得分:0)

使用工厂设计和策略设计如下

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#,我这两种方式都没问题。