如何设计一般搜索条件?

时间:2012-02-27 20:02:03

标签: c# .net design-patterns

假设我们有一个具有一组资源的应用程序(在服务器上):这些资源通过字典按名称索引,即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 个答案:

答案 0 :(得分:7)

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

就像现在一样,你将围绕可能永远不会存在的情况进行编程。你怎么知道什么时候“完成了?”

记住:YAGNI

答案 1 :(得分:4)

不要让客户向您发送您希望做的事情的课程,让他们发给您一个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)不允许它。即使有可能,这种方法感觉错误,并且 empty interface 正在产生严重的代码异味。我会说,使用定义明确的方法和参数类型,保持服务界面清晰简洁。

如果您希望用户通过各种不同的“策略”进行搜索,每个策略都需要一组不同的参数,请为每种潜在的搜索算法创建不同的方法(SearchByResourceNames(List<string resourceNames),{{1等等。)。

另一方面,如果您希望用户能够混合和匹配各种类型的条件,只需使用SearchByDomain(int domainId) DTO,让客户端填充他们想要搜索的属性。

答案 2 :(得分:0)

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

public delegate bool IsValidResource(Resource currentResource);

答案 3 :(得分:0)

查看Criteria Pattern @ Wikipedia是否可以为您提供帮助! 这是一种基于规范模式的软件模式。