Java - 如何设计搜索方法?

Java - How to design a method for search?

我正在设计一个包装新闻搜索引擎的装饰器 class,因此我们可以将此 class 与一个库一起发布以供其他团队使用。

这个class暴露的接口是Java风格的接口,它需要很多参数,然后这个装饰器将这些参数组装成搜索引擎的搜索文本。

我的方法是这样的:

public List<News> search(List<String> keywords, List<String> categories, List<String> authors, List<Location> locactions, List<LocalDate> dates, List<SortRule> sortRules, int offset, int limit);

是的,我知道...这个方法看起来长得可笑,非常容易出错并且很难为客户使用。

那么,我该如何设计更好的API这样的搜索功能呢?

您可以尝试编写一个包装器 class 来应用规则过滤器,然后在您当前的 class 中获取此 class 的新对象。这样就简单多了。

例如,

RuleFilters r = new RuleFilters();
r.addFilters(Type.Keywords, keywords);
r.addFilters(Type.Categories, categories);
r.addFilters(Type.Authors, authors);

此处 Type 是一个枚举,其中包含 {Categories, Authors, Keywords} 等不同规则过滤器的详细信息

终于在你的 Main Class:

public List<News> search(RuleFilters r) {
    /* Do Something with the rule filters */ 
};

接口:

List<News> search(RuleFilters r);

注意: public关键字在接口中不是必需的。

Effective Java 所述,您可以考虑使用构建器模式。这将是一个很好的解决方案。

SearchParam search = new SearchParam.Builder(keywords).
  categories(categories).authors(authors).location(loc1,loc2).build();

另一种方法是使用 bean 或 POJO 来传输搜索参数。 之后,您可以使用一些设计模式或过滤器来获得结果。但是对于只是价值运输来说,使用Bean还是不错的。

public class SearchParameters{

private List<String> keywords;
private List<String> categories;
private List<String> authors;
private List<Location> locactions;
private List<LocalDate> dates;
private List<SortRule> sortRules;
private int offset;
private int limit;
//Getters and Setters

}

//For one request
public List<News> search(SearchParameters param) {
    /* Do Something with the rule filters */ 
};

//for multiple request you could use List<SearchParameters> params

也许你可以看看 Elasticsearch Java library:

SearchResponse response = client.prepareSearch("news")
        .setQuery(QueryBuilders.termQuery("author", "jack"))               // Query
        .setPostFilter(QueryBuilders.rangeQuery("date_published").from('2016-04-01').to('2016-04-30'))   // Filter
        .setFrom(0).setSize(10)
        .execute()
        .actionGet();

这基本上是构建器模式的专门实现。