问题
I have a java class SearchFilterWebPage
which represents a web page for an online shopping website. All of its (filter) methods allow you to set a filter, just like you would on a real shopping website. For example enterPriceRange(min, max), selectBrandsFilter(String...brands), and selectFreeShippingOnlyFilter()
. The below code is very simple and only prints messages.
I made a function applyMultipleFilters(FilterCommand [] functions)
which allows you to call any number of filter functions of SearchFilterWebPage
class. Each filter function is represented by an instance of FilterCommand
, i.e. the command pattern. For example, enterPriceRange(min, max), and selectBrandsFilter(String...brands)
are represented by EnterPriceRangeFilter and SelectBrandsFilter
classes respectively.
Basically, I made a class to represent each filter function. Can someone please tell me if this is a good idea ? Is there any other way besides reflection and the command pattern to implement applyMultipleFilters(...)
?
Class with main method :
public class SearchFilterWebPage {
public void enterPriceRangeFilter(int min, int max){
System.out.println("enterPriceRangeFilter");
}
public void selectBrandsFilter(String...brands){
System.out.println("selectBrandsFilter");
}
public void selectFreeShippingOnlyFilter(){
System.out.println("selectFreeShippingOnlyFilter");
}
//NOTE - Add 5 or more functions like the above ones !!!
//MAIN METHOD
public static void main(String [] main){
SearchFilterWebPage search = new SearchFilterWebPage();
FilterCommand [] filters = {
new EnterPriceRangeFilter(search, 50, 100),
new SelectBrandsFilter(search, "Adidash", "Nikki", "Pooma")
};
search.applyMultipleFilters(filters);
}
public void applyMultipleFilters(FilterCommand [] functions){
for(FilterCommand fun : functions){
fun.execute();
}
}
}
Output:
>>> EXECUTING : enterPriceRangeFilter
>>> EXECUTING : selectBrandsFilter
Supporting code:
Command:
public interface FilterCommand {
void execute();
}
Filter:
public class EnterPriceRangeFilter implements FilterCommand {
private final int min;
private final int max;
private final SearchFilterWebPage search;
public EnterPriceRangeFilter(SearchFilterWebPage search, int min, int max) {
this.search = search;
this.min = min;
this.max = max;
}
@Override
public void execute() {
//Use min, max.
System.out.print(">>> EXECUTING : " );
search.enterPriceRangeFilter(min, max);
}
}
Filter:
public class SelectBrandsFilter implements FilterCommand {
private final String [] brands;
private final SearchFilterWebPage search;
public SelectBrandsFilter(SearchFilterWebPage search, String...brands) {
this.search = search;
this.brands = brands;
}
@Override
public void execute() {
//Use brands.
System.out.print(">>> EXECUTING : ");
search.selectBrandsFilter(brands);
}
}
UPDATE 1:
Suppose that there are many tests/functions which could use different combinations of filters. But, some of these tests/functions use the exact same set of filters. So, I thought of creating combinations of filters which could be reused in different tests/functions. There are two possible solutions to create such combinations that I can think of at the moment.
Solution 1 - Create a FilterChoices class which will provide all the filtering data to the SearchFilterWebPage. FilterChoices can be a simple POJO with getters and setters. We could use the builder pattern to build this. The minor problem is that applyMultipleFilters(...) function will need to do multiple checks to see which all filters have been set in FilterChoices and call the appropriate filter functions.
Solution 2 - Use the command pattern as mentioned in this post. Unfortunately, we end up creating a lot of code (even if simple) just to avoid checking for which filter functions to call.
来源:https://stackoverflow.com/questions/61284856/design-pattern-is-this-a-good-way-to-use-the-command-pattern