2012-01-12 39 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); 
    } 
}