0

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

  1. 用户在 Web 界面上显示,并针对流程使用不同的算法
  2. 用户选择存储在数据库中。
  3. 现在,应用程序应该根据所选算法执行不同的计算。

什么是实施这个的好策略?现在我们正在做的是——

  1. 有一个参考数据库表,其中包含所有算法类型和代码中相应的类名(例如,如果是快速排序算法,那么我们存储 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 是从数据库中的引用表中加载的所有类类型的列表。

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

4

3 回答 3

2

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

于 2009-07-24T22:31:24.000 回答
2

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

创建一个接口 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];
    }
}

你所有的排序算法现在都可以实现这个接口。

 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 回答
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#,否则我觉得这两种方法都可以。

于 2009-07-24T22:40:41.360 回答