C# 不同输入的不同算法

C# 不同输入的不同算法,c#,design-patterns,strategy-pattern,C#,Design Patterns,Strategy Pattern,在我开发的应用程序中,我面临着一种情况;我想知道是否有这种设计模式。如下 public interface ISorter { // Prototype for your sort function goes here } public class QuickSorter implements ISorter {} public class SorterFactory { public ISorter getSorter( string sortType ) { //

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

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();
      }
   }
}
  • 用户可以在web界面上使用不同的流程算法进行演示
  • 用户选择存储在数据库中
  • 现在,应用程序应该根据选择的算法执行不同的计算 实施这一目标的好策略是什么?现在我们正在做的是-

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

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


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

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

    是的,您是对的,你想要的是图案。但是,您真正想做的是定义一个接口,每个算法都使用该接口,该接口允许您为算法指定参数,并允许您通过该接口调用每个参数,不要用你在问题中描述的丑陋的反映过程。

    使用工厂设计和策略设计,如下所示

    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#,我认为任何一种方法都可以。

    使用工厂设计和策略设计,如下所示

    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#,我认为这两种方法都可以。

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

    创建接口IMySortingAlgorithms作为

    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];
        }
    }
    
    这样,每当您创建一个新的类进行排序时,就不需要将类名添加到数据库中

    以下是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;
                        }
                    }
                }
            }
    
    //
    ///对于当前应用程序域中的所有关联,
    ///给我所有实现IMySortingAlgorithms的类型的对象
    /// 
    静态MyAlgoFactory()
    {
    m_dict=新字典();
    变量类型=类型(IMySortingAlgorithms);
    foreach(AppDomain.CurrentDomain.GetAssemblys()中的程序集asm)
    {
    foreach(在asm.GetTypes()中键入p)
    {
    if(type.IsAssignableFrom(p)&&p!=type)
    {
    IMySortingAlgorithms algo=Activator.CreateInstance(p)
    作为IMySortingAlgorithms;
    m_dict[算法名]=算法;
    }
    }
    }
    }
    
    您可以使用接口+反射来避免在数据库中存储算法名称

    创建接口IMySortingAlgorithms作为

    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];
        }
    }
    
    这样,每当您创建一个新的类进行排序时,就不需要将类名添加到数据库中

    以下是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;
                        }
                    }
                }
            }
    
    //
    ///对于当前应用程序域中的所有关联,
    ///给我所有实现IMySortingAlgorithms的类型的对象
    /// 
    静态MyAlgoFactory()
    {
    m_dict=新字典();
    变量类型=类型(IMySortingAlgorithms);
    foreach(AppDomain.CurrentDomain.GetAssemblys()中的程序集asm)
    {
    foreach(在asm.GetTypes()中键入p)
    {
    if(type.IsAssignableFrom(p)&&p!=type)
    {
    IMySortingAlgorithms algo=Activator.CreateInstance(p)
    作为IMySortingAlgorithms;
    m_dict[算法名]=算法;
    }
    }
    }
    }
    
    您刚才不是用开关/if-else替换了satyajit的反射吗?我同意这有点策略的味道,但这并不能很好地改善情况。。您刚刚又添加了一个地方(工厂),如果添加了更多策略,代码需要在那里更改。是的,Torbjorn,在代码和数据库中。这就是我想要消除的。有人能理解我的痛苦吗?今天我创建了一个新的算法,比如CBigBadSortingAlgorithm.cs,我必须转到后端并将这个名称添加到数据库中。我担心,如果将来模式发生变化,会发生什么情况?谁会跟踪所有这些?他为什么要将名称添加到数据库中?为什么不根据单击的复选框分配一个字符串并将其传递到工厂?您不是刚刚用开关/if-else替换了satyajit的反射吗?我同意这有点策略的味道,但这并不能很好地改善情况。。Y