2012-01-12 83 views
5

我需要在用戶通過下拉列表選擇條件後過濾和排序數據條目。可選擇的將是諸如「最新的條目第一」,「最早的條目第一」,「最低的價格第一」等等。哪種設計模式用於排序和過濾數據?

我可以創建一個枚舉選項和開關/案例我檢索數據, d而是以一種容易擴展的方式來做到這一點。

什麼設計模式最適合這種情況?

+1

winforms,wpf,silverlight,webforms或mvc? – 2012-01-12 15:28:30

+1

我想戰略模式會做.. – VS1 2012-01-12 15:29:35

+1

WebForms,但不是一個普遍的問題? – magnattic 2012-01-12 15:32:12

回答

3

大家都提到了戰略模式。只是想我會發布我的簡單實施。沒有必要使它比必要的更復雜。

public enum SortMethod 
{ 
    Newest, 
    Oldest, 
    LowestPrice, 
} 

public class Foo 
{ 
    public DateTime Date {get;set;} 
    public decimal Price {get;set;} 
} 


... 
var strategyMap = new Dictionary<SortMethod, Func<IEnumerable<Foo>, IEnumerable<Foo>>> 
        { 
         { SortMethod.Newest, x => x.OrderBy(y => y.Date) }, 
         { SortMethod.Oldest, x => x.OrderByDescending(y => y.Date) }, 
         { SortMethod.LowestPrice, x => x.OrderBy(y => y.Price) } 
        }; 

... 
var unsorted = new List<Foo> 
       { 
        new Foo { Date = new DateTime(2012, 1, 3), Price = 10m }, 
        new Foo { Date = new DateTime(2012, 1, 1), Price = 30m }, 
        new Foo { Date = new DateTime(2012, 1, 2), Price = 20m } 
       }; 

var sorted = strategyMap[SortMethod.LowestPrice](unsorted); 
+0

偉大的作品,優雅和簡單。謝謝! – magnattic 2012-03-09 19:17:07

0

我並不總是善於根據自己的想法命名正確的模式,但我最初的想法是爲什麼不爲每個選項做一個簡單的類並實現IComparer(T),然後將這些項作爲下拉選項加載。除了接口方法外,您可能只需要一個名稱屬性。

public class NameSorter: IComparer<WhateverObj> 
{ 
public String DisplayName;  

public int Compare(WhateverObj x, WhateverObj y) 
{ 

} 
} 
0

正如在評論中提到的,這聽起來像是Strategy pattern的工作。您將會認識到這一點,因爲它已經在.NET框架中佔有很大的比例。

下面是一個使用IComparer的例子,或者使用3.5中我喜歡的LINQ擴展方法。您仍然需要向基類中添加一個工廠樣式的方法來確定應該使用哪個比較器,或者您可以將其作爲數據的一部分存儲在下拉列表中。

static void Main(string[] args) 
{ 

    List<User> users = new List<User>(); 
    users.Add(new User() { Name = "Larry", Age = 35 }); 
    users.Add(new User() { Name = "Bob", Age = 25 }); 
    users.Add(new User() { Name = "Brian", Age = 30 }); 

    NameComparer sorter = new NameComparer(); 
    IEnumerable<User> sortedUsers = sorter.Sort(users); 

    NameComparer35 sorter35 = new NameComparer35(); 
    IEnumerable<User> sortedUsers35 = sorter35.Sort(users); 
} 

public abstract class MyComparer<T> : IComparer<T> where T: User 
{ 
    public abstract int Compare(T x, T y); 

    public IEnumerable<T> Sort(IEnumerable<T> items) 
    { 
     items.ToList().Sort(this); 
     return items; 
    } 
} 

public abstract class MyComparer35<T> where T : User 
{ 
    public abstract IEnumerable<T> Sort(IEnumerable<T> items); 
} 

public class NameComparer35 : MyComparer35<User> 
{ 
    public override IEnumerable<User> Sort(IEnumerable<User> items) 
    { 
     return items.OrderBy(u => u.Name); 
    } 
} 

public class NameComparer : MyComparer<User> 
{ 
    public override int Compare(User x, User y) 
    { 
     return x.Name.CompareTo(y.Name); 
    } 
} 

public class AgeComparer : MyComparer<User> 
{ 
    public override int Compare(User x, User y) 
    { 
     return x.Age.CompareTo(y.Age); 
    } 
} 

public class User 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 

    public override string ToString() 
    { 
     return string.Format("{0} {1}", Name, Age); 
    } 
}