Reputation: 2329
I am designing a decorator class which wraps a news search engine, so we can ship this class with a library to be used by other teams.
The exposed interface of this class is a Java-styled one, it takes a lot of parameters, then this decorator assembles these parameters as a search text to the search engine.
My method is something like the following:
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);
Yes, I know... This method looks ridiculously long, very error-probe and hard to use for the clients.
So, how can I design a better API for such a search functionality?
Upvotes: 6
Views: 3181
Reputation: 5381
Maybe you can take look on the 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();
Which is basically a specialized implementation of the Builder pattern.
Upvotes: 0
Reputation: 1997
Another way is by using bean or POJO for transporting Search Parameters. After that you can use Some design pattern or filters to get results. But for just value transportation it is good to use 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
Upvotes: 0
Reputation: 1508
As noted in Effective Java,You may consider using Builder Pattern. And that would be neat solution.
SearchParam search = new SearchParam.Builder(keywords).
categories(categories).authors(authors).location(loc1,loc2).build();
Upvotes: 7
Reputation: 9648
You can try writing a wrapper class for applying the rule filters and then take the new object of this class in your current class. This way it would be much simple and cleaner.
For Example,
RuleFilters r = new RuleFilters();
r.addFilters(Type.Keywords, keywords);
r.addFilters(Type.Categories, categories);
r.addFilters(Type.Authors, authors);
Here Type
is an enum which holds the details of the different rule filters like {Categories, Authors, Keywords}
etc.
Finally in your Main Class:
public List<News> search(RuleFilters r) {
/* Do Something with the rule filters */
};
Interface:
List<News> search(RuleFilters r);
Note: public
keyword is not necessary in interfaces.
Upvotes: 7