本文主要介绍行为参数化
基础概念
- 行为参数化:将方法或代码作为
参数或值
进行传递
- 谓词:一个返回
boolean
值的函数,在 Java8
中是一个函数式接口
(java.util.function.Predicate
)
代码实例
目录结构如下,相关代码托管在java8_demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| ├── main │ └── java │ └── me │ └── zhongmingmao │ ├── domain │ │ └── Apple.java │ ├── filter │ │ ├── FilterJava7.java │ │ └── FilterJava8.java │ └── predicate │ ├── java7 │ │ ├── ColorPredicate.java │ │ ├── PredicateJava7.java │ │ └── WeightPredicate.java │ └── java8 │ └── PredicateJava8.java └── test └── java └── me └── zhongmingmao └── predicate └── PredicateJavaTest.java
|
Java7 + 策略模式
Apple
1 2 3 4 5 6 7 8
| @Data @AllArgsConstructor public class Apple { public enum COLOR { GREEN, RED } public static final int HEAVY_WEIGHT = 200; private COLOR color; private int weight; }
|
PredicateJava7
1 2 3
| public interface PredicateJava7 { boolean test(Apple apple); }
|
ColorPredicate
1 2 3 4 5 6
| public class ColorPredicate implements PredicateJava7 { public boolean test(Apple apple) { return null == apple ? false : Apple.COLOR.GREEN.equals(apple.getColor()); } }
|
WeightPredicate
1 2 3 4 5 6
| public class WeightPredicate implements PredicateJava7 { public boolean test(Apple apple) { return null == apple ? false : apple.getWeight() > Apple.HEAVY_WEIGHT; } }
|
FilterJava7
1 2 3 4 5 6 7 8 9 10 11
| public class FilterJava7 { public static List<Apple> filterJava7(List<Apple> apples, PredicateJava7 predicateJava7) { List<Apple> result = new ArrayList<Apple>(); for (Apple apple : apples) { if (predicateJava7.test(apple)) { result.add(apple); } } return result; } }
|
PredicateJavaTest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class PredicateJavaTest {
private List<Apple> apples = null;
@Before public void setUp() { apples = Arrays.asList(new Apple(Apple.COLOR.GREEN, 100), new Apple(Apple.COLOR.RED, 300)); }
@Test public void predicateJava7Test() { assertEquals(1, FilterJava7.filterJava7(apples, new ColorPredicate()).size()); assertEquals(1, FilterJava7.filterJava7(apples, new WeightPredicate()).size()); } }
|
从ColorPredicate
和WeightPredicate
可以看出,每实现一个策略都会需要重复相应的模板代码
Java8 + Lambda + 泛型
PredicateJava8
1 2 3
| public interface PredicateJava8<T> { boolean test(T t); }
|
FilterJava8
1 2 3 4 5 6 7 8 9 10 11 12
| public class FilterJava8 {
public static <T> List<T> filterJava8(List<T> list, PredicateJava8<T> predicateJava8) { List<T> result = new ArrayList<T>(); for (T t : list) { if (predicateJava8.test(t)) { result.add(t); } } return result; } }
|
与FilterJava7
,相比仅仅是引入了泛型
PredicateJavaTest
增加测试用例predicateJava8Test
1 2 3 4 5 6
| @Test public void predicateJava8Test() { assertEquals(1, FilterJava8.filterJava8(apples, (Apple apple) -> Apple.COLOR.GREEN.equals(apple.getColor())).size()); assertEquals(1, FilterJava8.filterJava8(apples, apple -> apple.getWeight() > Apple.HEAVY_WEIGHT).size()); }
|
采用 Lambda
表达式实现行为参数化
无需先定义相应的策略,减少模板代码
的产生