用于排序和筛选数据的设计模式

本文关键字:设计模式 数据 筛选 排序 用于 | 更新日期: 2023-09-27 18:20:03

我需要根据用户通过下拉列表选择的条件筛选和排序数据条目。可选择的内容包括"最新条目优先"、"最旧条目优先"answers"最低价格优先"等。

我可以为选项创建一个枚举,并在其中切换/case来检索数据,但我更愿意以一种易于扩展的方式来做这件事。

什么样的设计模式最适合这种情况?

用于排序和筛选数据的设计模式

每个人都提到了战略模式。我只是想发布我的简单实现。没有必要让它变得比必要的更复杂。

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);

我并不总是善于根据自己的想法命名正确的模式,但我最初的想法是,为什么不为每个选项创建一个简单的类,并实现IComparer(T),然后将这些项加载为下拉选项。除了接口方法之外,您可能只需要一个name属性。

public class NameSorter: IComparer<WhateverObj>
{
public String DisplayName;    
public int Compare(WhateverObj x, WhateverObj y)
{
}
}

正如评论中提到的,这听起来像是Strategy模式的一项工作。您将认识到这一点,因为它已经在.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);
    }
}