我需要根据用户通过下拉选择的条件来过滤和排序数据条目。可选的条件包括“最新条目优先”,“最旧条目优先”,“最低价格优先”等。
我可以只为选项创建枚举,并在检索数据时进行switch / case,但我更希望以易于扩展的方式完成此操作。
哪种设计模式最适合这种情况?
我需要根据用户通过下拉选择的条件来过滤和排序数据条目。可选的条件包括“最新条目优先”,“最旧条目优先”,“最低价格优先”等。
我可以只为选项创建枚举,并在检索数据时进行switch / 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),然后将这些项目作为下拉选项加载。除了接口方法之外,您可能只需要一个名称属性。
public class NameSorter: IComparer<WhateverObj>
{
public String DisplayName;
public int Compare(WhateverObj x, WhateverObj y)
{
}
}
如评论中所提到的,这似乎是策略模式的工作。你会发现它已经在.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);
}
}