代码之家  ›  专栏  ›  技术社区  ›  satyajit

不同输入的不同算法[关闭]

  •  0
  • satyajit  · 技术社区  · 15 年前

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

    1. 用户在Web界面上出现,具有不同的流程算法
    2. 用户选择存储在数据库中。
    3. 现在,应用程序应该根据选择的算法执行不同的计算。

    实现这一目标的好策略是什么?现在我们要做的是-

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

      system.reflection.assembly types=system.reflection.assembly.loadfile(system.reflection.assembly.getExecutingAssembly().location.toString());
      foreach(类型T) 如果(t.name==classname) 创建实例(t) //classname是从数据库中的引用表加载的所有类类型的列表。

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

    3 回复  |  直到 15 年前
        1
  •  2
  •   chikak    15 年前

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

    创建接口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
        }
    

    这样,每当您创建一个用于排序的新类时,就不需要将类名添加到数据库中。

    下面是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;
                        }
                    }
                }
            }
    
        2
  •  2
  •   Paul Sonier    15 年前

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

        3
  •  0
  •   DevDevDev    15 年前

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

    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语言,任何一种方式对我都是好的。