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();
这基本上是构建器模式的专门实现。
我正在设计一个包装新闻搜索引擎的装饰器 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();
这基本上是构建器模式的专门实现。