【Java8】 行为化参数

来源:互联网 发布:天鹰行动23.d vb 编辑:程序博客网 时间:2024/06/06 09:42

需求

​ 有一个苹果集合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都是行为参数化的实现形式。 相对于第一,第二种解决方式,第三种是传递了一个行为,而前面两种你均是传递值。通过使用行为作为一个参数,只需要定义具体的行为,可以使用同一个接口灵活地对付各种变更需求。

原创粉丝点击