Как я могу разработать общие критерии поиска? - PullRequest
4 голосов
/ 28 февраля 2012

Предположим, у нас есть приложение (на сервере), которое имеет набор ресурсов: эти ресурсы индексируются по имени через словарь, то есть Dictionary<string, Resource> resources.

Клиент отправляет на сервер (используяWCF) имена одного или нескольких ресурсов (например, он отправляет List<string>).На сервере может быть только подмножество ресурсов, запрошенных клиентом, поэтому, когда сервер получает этот список, он отправляет обратно список, содержащий только имена найденных ресурсов.

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

public interface ISearchCriteria
{
    // the names of the resources which match with the search criteria
    ICollection<string> GetCompliantResources();
}

Однако мне кажется, что это решение не оченьправильно, потому что метод GetComplianceResources должен взаимодействовать со словарем на сервере, но клиент не должен ничего знать об этом словаре ... Я мог бы использовать шаблон стратегии , связывая каждую конкретную стратегию с конкретнойкритерий поиска.Таким способом можно отделить логику управления от данных (т. Е. Критериев поиска).

ОБНОВЛЕНИЕ (шаблон стратегии и DTO)

// Both on the server and on the client
public interface ISearchCriteria
{
    // empty
}

// Both on the server and on the client
public class DefaultSearchCriteriaDTO : ISearchCriteria
{
    List<string> ResourceNames { get; set; }
    List<int> OtherCriteria { get; set; }
}

// Both on the server and on the client
public class MySearchCriteriaDTO : ISearchCriteria
{
    string SearchString { get; set; }
}

// On the server.
public interface IStrategy<T> : where T : ISearchCriteria
{
    public List<string> Match(T criteria);
}

// On the server
public class DefaultStrategy : IStrategy<T> where T : DefaultSearchCriteriaDTO
{
    public List<string> Match(T criteria)
    {
        // search for resources and returns those found
    }
}
  • Есть какой-то шаблон дизайна для этой цели?
  • Есть ли лучшие альтернативы?

Ответы [ 4 ]

7 голосов
/ 28 февраля 2012

Честно говоря, я бы этого не реализовал, пока в этом нет необходимости.

Как сейчас, вы будете программировать вокруг ситуаций, которые могут никогда не существовать. Как вы узнаете, когда вы закончите?

Помните: ЯГНИ .

4 голосов
/ 28 февраля 2012

Вместо того, чтобы требовать от клиента отправки вам класса, который, как вы ожидаете, будут делать, пусть он отправит вам POCO:

public class SearchCriteria
{
    List<string> ResourceNames { get; set; }
    // Add more properties here in the future as you identify additional criteria
}

Когда вы добавляете свойства в связанный POCO, люди, использующие более старую версию вашего API, могут по-прежнему работать со своим кодом, если протокол привязки интерпретирует отсутствие свойства, что означает, что свойство не должно быть установлено.

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

Обновление

Глядя на предполагаемое использование модели стратегии, я думаю, вы слишком усложняете вещи. Во-первых, я даже не знаю, может ли WCF связываться с различными типами параметров в зависимости от того, какой тип объекта пытается отправить пользователь: конечно, есть, по крайней мере, некоторые привязки (например, JSON), которые этого не позволяют. Даже если это возможно, этот подход кажется неправильным, и пустой интерфейс вызывает серьезный запах кода . Я бы сказал, чтобы интерфейс вашего сервиса был ясным и простым, с четко определенными методами и типами параметров.

Если вы ожидаете, что пользователи будут искать с помощью различных «стратегий», каждая из которых потребует различного набора параметров, создайте свой метод для каждого потенциального алгоритма поиска (SearchByResourceNames(List<string resourceNames), SearchByDomain(int domainId) и т. Д.). .).

С другой стороны, если вы хотите, чтобы пользователь мог смешивать и сопоставлять различные типы критериев, просто используйте SearchCriteria DTO и позвольте клиенту заполнять любые свойства, по которым он хочет искать.

0 голосов
/ 03 июля 2013

Посмотрите, может ли Criteria Pattern @ Wikipedia помочь вам! Это программный шаблон, основанный на шаблоне спецификации.

0 голосов
/ 28 февраля 2012

Я бы создал ISearchCriteria с методом, который возвращает bool и принимает Resource в качестве параметра.Метод ISearchCriteria вызывается для каждого ресурса и возвращает true, если вы хотите, чтобы ресурс был включен в список возврата.Вы также можете реализовать это с помощью делегатов вместо интерфейсов, например:

public delegate bool IsValidResource(Resource currentResource);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...