Какой шаблон проектирования для упорядочения и фильтрации данных? - PullRequest
5 голосов
/ 12 января 2012

Мне нужно отфильтровать и упорядочить записи данных по критериям, которые пользователь выбирает из раскрывающегося списка.Для выбора будут выбраны такие вещи, как «сначала самые новые записи», «сначала самые старые записи», «сначала самая низкая цена» и т. Д.Я бы предпочел сделать это легко расширяемым способом.

Какой шаблон проектирования лучше всего подходит для ситуации?

Ответы [ 3 ]

3 голосов
/ 12 января 2012

Каждый упомянул шаблон стратегии. Просто думал, что выложу свою простую реализацию. Не нужно усложнять это, чем нужно.

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 голосов
/ 12 января 2012

Как уже упоминалось в комментариях, это звучит как работа для паттерна стратегии .Вы поймете это, так как это уже широко используется в .NET Framework.

Вот пример использования IComparer или использования методов расширения LINQ в 3.5, которые я предпочитаю.Вам все равно нужно добавить метод базового стиля в базовый класс, который определяет, какой компаратор он должен использовать, или вы можете сохранить его как часть данных в раскрывающемся списке.

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);
    }
}
0 голосов
/ 12 января 2012

Я не всегда умею называть правильный шаблон в соответствии со своей мыслью, но моя первоначальная мысль - почему бы не создать простой класс для каждой опции и не реализовать IComparer (T), а затем загрузить эти элементы в качестве выпадающих опций. Скорее всего, вам понадобится только свойство name в дополнение к методу интерфейса.

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

public int Compare(WhateverObj x, WhateverObj y)
{

}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...