Создание общего интерфейса ввода параметров фильтра? - PullRequest
1 голос
/ 09 сентября 2011

У меня есть вызовы методов, которые принимают разные входные данные, например:

public Authors GetAuthors(string name, string sortBy, string sortDir, int startRow, int numRow)
{
    // Get authors based on filters
}

public Books GetBooks(string id, string year, string sortBy, string sorDir, int startRow, int numRow)
{
    // Get books based on filters
}

Я планирую изменить его так, чтобы фильтры были объектами, например:

public Authors GetAuthors(GetAuthorsFilters filters)
{
    // Get authors based on filters
}

public Books GetBooks(GetBooksFilters filters)
{
    // Get books based on filters
}

Но многиеФильтры являются общими для всех методов, и я хотел бы создать для этого общий интерфейс (т. е. IFilter), который может принимать различные объекты фильтра, но не уверен, с чего начать.Любое предложение или рекомендация?

Спасибо.

Ответы [ 2 ]

3 голосов
/ 09 сентября 2011

Похоже, вы хотите иметь некоторые общие функции между всеми фильтрами. Вы хотели бы реализовать это не обязательно через интерфейс, а через абстрактный базовый класс. Кроме того, поскольку вы будете фильтровать разные объекты, имело бы смысл использовать дженерики. Вы можете получить что-то вроде следующего:

public class FilterBase<T> {
    protected int startRow;
    ...

    public FilterBase(Func<T, IComparable> sortBy, bool sortAscending, int startRow, int numRow) {
        //assigns to member variables
    }

    public IEnumerable<T> Filter(IEnumerable<T> toFilter) {
        filtered = DoFiltering(toFilter);
        filtered = DoPaging(filtered);
        filtered = DoSorting();
        return filtered;
    }

    protected abstract IEnumerable<T> DoFiltering(IEnumerable<T> toFilter);
    protected virtual IEnumerable<T> DoPaging(IEnumerable<T> toFilter) {
        return toFilter.Skip(startRow).Take(numRow);
    }
    protected virtual IEnumerable<T> DoSorting(IEnumerable<T> toFilter) {
        return sortAscending ? toFilter.OrderBy(sortBy) : toFilter.OrderByDescending(sortBy);
    }
}

public class BookFilter : FilterBase<Book> {
    public BookFilter(string id, string year, string sortBy, string sorDir, int startRow, int numRow) : base(sortBy, sorDir, startRow, numRow) {
        //assign id and year to member variables
    }

    protected override IEnumerable<Book> DoFiltering(IEnumerable<Book> toFilter) {
        return toFilter.Where(b => b.Id == id && b.Year == year);
    }
}

Это позволит вам определить логику подкачки и сортировки один раз для всех типов фильтров, и каждый из этих типов определит свою собственную пользовательскую фильтрацию на основе своих закрытых членов и типа объекта, на который они ссылаются.

3 голосов
/ 09 сентября 2011

По-моему, я бы использовал абстрактный класс, чтобы составить то, что вы ищете.Вы можете создать интерфейс для каждого типа поиска, но тогда вам придется каждый раз реализовывать интерфейс, и кажется, что между вашими общими свойствами в BookFilters и AuthorFilters нет программной разницы.Может быть что-то вроде:

public abstract class BaseFilter
{
    public string SortBy { get; set; }
    public bool SortAscending { get; set; }
    public int RowStart { get; set; }
    public int RowCount { get; set; }
}

public class BookFilter : BaseFilter
{
    public string ISBN { get; set; }
    public int Year { get; set; }
}

public class AuthorFilter : BaseFilter
{
    public string Name { get; set; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...