如何设计通用搜索条件

本文关键字:搜索 条件 | 更新日期: 2023-09-27 18:25:54

假设我们有一个应用程序(在服务器上),它有一组资源:这些资源通过字典按名称进行索引,即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
    }
}
  • 有没有这种设计模式
  • 有更好的选择吗

如何设计通用搜索条件

老实说,在需要它之前,我不会实现它。

现在,你将围绕着可能永远不存在的情况进行编程。你怎么知道你什么时候"完成"

记住人:YAGNI。

与其要求客户端向您发送一个您希望执行的类,不如让他们向您发送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,并让客户端填充他们想要搜索的任何属性。

我会用一个返回bool并接受Resource作为参数的方法创建ISearchCriteria。ISearchCriteria的方法会为每个资源调用,如果希望资源包含在返回列表中,则返回true。您也可以使用委托而不是接口来实现这一点,比如:

public delegate bool IsValidResource(Resource currentResource);

看看Criteria Pattern@Wikipedia是否能帮到你!它是一种基于规范模式的软件模式。