需求
有一个苹果集合appleList ,筛选出红色的苹果 。苹果实体类如下
public class Apple {
private String color;
private int weight;
//getter and setter
}
解决方案一
写一个过滤红色苹果的方法即可:
public static List<Apple> filterRedApples(List<Apple> appleList){
List<Apple> result = new ArrayList<>();
for (Apple apple : appleList) {
if(apple.getColor().equals("red")){
result.add(apple);
}
}
return result;
}
不足:当要筛选出绿色的苹果时,又得重新定义个filterGreenApples,当帅选的条件越多,需要定义的方法也会线性增长。
解决方案二
将帅选的条件作为参数传入方法中,即当需要筛选不同颜色的苹果时只要传入响应的参数进入即可:
public static List<Apple> filterRedApples(List<Apple> appleList, String color){
List<Apple> result = new ArrayList<>();
for (Apple apple : appleList) {
if(apple.getColor().equals(color)){
result.add(apple);
}
}
return result;
}
不足:虽能很好的解决了当前的问题,但是当需求变更时,如既要帅选红色的苹果还是帅选出重量大于150克的苹果的话,还得重新写一个帅选苹果重量的filterWeightApples方法,且这些方法之间并没有任何关联,变得相当松散,并不利于维护。
解决方案三
统一个过滤接口,需要不同的过滤条件时则写个过滤条件类即可。
//定义一个过滤的接口
public interface ApplePredicate {
boolean test(Apple apple);
}
//过滤出红色的苹果
public class AppleRedColorPredicate implements ApplePredicate {
@Override
public boolean test(Apple apple) {
return apple.getColor().equals("red");
}
}
//过滤出大于150克的苹果
public class Apple150HeavyWeightPredicate implements ApplePredicate {
@Override
public boolean test(Apple apple) {
return apple.getWeight() > 150;
}
}
不管需求是啥,只要通过下面同一个过滤方法都可以实现过滤。
public static List<Apple> filterApples(List<Apple> appleList, ApplePredicate predicate){
List<Apple> result = new ArrayList<>();
for(Apple apple : appleList){
if(predicate.test(apple)){
result.add(apple);
}
}
return result;
}
这种方式叫做行为参数化,可以通过调用同一个重复的方法来实现不同的行为。说白了,就是一个接口,多个实现类,也就是面向对象里面的多态机制,对应的是设计模式中的策略模式。
对于上面的各种不同实现类,在Java里面也可以不单独写,直接使用匿名类就好。如:
List<Apple> result = filterApples(appleList, new ApplePredicate() {
@Override
public boolean test(Apple apple) {
return apple.getColor().equals("red");
}
});
如果是使用Java8,我们可以对上面的代码块用Lambda表达式进行重写。
List<Apple> result = filterApples(apples , (Apple apple) -> {
return apple.getColor().equals("red");
});
实现类,匿名类和Lambda都是行为参数化的实现形式。 相对于第一,第二种解决方式,第三种是传递了一个行为,而前面两种你均是传递值。通过使用行为作为一个参数,只需要定义具体的行为,可以使用同一个接口灵活地对付各种变更需求。