2009-07-24 26 views
0

在我正在開發的應用程序中,我面臨着一種情況;我想知道是否有這樣的設計模式。這是如下針對不同輸入的不同算法

  1. 用戶呈現不同的算法,一個Web界面上的過程
  2. 用戶選擇存儲在數據庫中。
  3. 現在,應用程序應根據所選算法以不同的方式執行計算。

什麼是一個很好的策略來實現這個?現在我們正在做的是 -

  1. 具有帶有所有的算法類型和代碼對應的類名稱的參考數據庫表(例如,如果快速排序算法,然後我們店裏快速排序)。每當新算法出現時都必須手動更新
  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中的引用表中加載的所有類類型的列表。

我的直覺是應該有一個更簡單/更好的方法來做到這一點,因爲它似乎是一個非常標準的問題。我知道strategy pattern - 但我想要的是簡化並可能刪除手動任務。

+0

我的基本問題的非LINQ的版本是 - 怎麼知道實例是什麼類型?我所擁有的解決方案並不高雅,我認爲這種情況非常普遍,我希望一些實際做到這一點的人可以給我提供建議。 – satyajit 2009-07-25 02:39:11

回答

2

您可以使用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]; 
    } 
} 

所有的排序算法現在都可以實現這個接口。

public class MySortingAlgo1 : IMySortingAlgorithms 
    { 
     #region IMySortingAlgorithms Members 

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

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

     #endregion 
    } 

這樣,無論何時創建一個新的類進行排序,都無需向數據庫添加類名稱。

以下是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

是的,你是對的,你想要的是Strategy模式。然而,你真正想要做的是定義一個接口,你的每個算法都使用它來允許你指定算法的參數,並且允許你通過接口簡單地調用它們中的每一個,而不是你的糟糕的反射過程在問題中描述。

+1

+1 - 打我吧:) – 2009-07-24 22:34:23

+0

我會爭辯說,satyajit做過的一件事就是實施策略。它可能會或可能會注意使用通用接口。 – 2009-07-24 23:51:29

+0

@ Torb0rn:我不同意OP做的是Strategy的實施;他特意要求一種更簡單/更好的方式,我認爲定義一個管理策略的界面是可行的。 – 2009-07-25 00:05:48

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#,否則任何一種方式都可以。