一、概念
行为参数化是一种可以处理频繁变更的需求的一种软件开发模式。
一个方法接受多个不同的行为作为参数,在内部使用它们,从而实现不同的行为能力。
即:将不同的代码块(行为)当做参数传递给方法,使得方法可以执行多种行为。
二、思路演变
需求设定:农场主要求根据苹果的重量挑选苹果,重量大于150g
1、在方法中直接写行为逻辑
public List<Apple> getApplesByWeight(List<Apple> apples) {
List<Apple> result = new ArrayList<Apple>();
for ( Apple a : apples) {
if ( a.getWeight() > 150 ) result.add(a);
}
return result;
}
需求变更:现在不需要150g以上的苹果了,需要120g的
2、将重量抽离成参数
public List<Apple> getApplesByWeight(List<Apple> apples, int weight) {
List<Apple> result = new ArrayList<Apple>();
for ( Apple a : apples) {
if ( a.getWeight() > weight ) result.add(a);
}
return result;
}
需求变更:现在要根据颜色和重量筛选苹果,颜色为绿色,重量大于120g
或者:我们要根据更多的属性来筛选呢?
3、行为参数化
对于各种变化的筛选条件,我们应该将其抽象出来,变为接口,这样我们就可已通过不同的实现类来实现不同的筛选条件
3.1使用实现类来实现行为参数化,多个实现类的时候代码繁琐
interface ApplePredicate{
boolean filter(Apple apple);
}
class ApplePredicateByWeight implement{
public boolean filter(Apple apple) { }
}
public List<Apple> getApples(List<Apple> apples, ApplePredicateByWeight predicate) {
List<Apple> result = new ArrayList<Apple>();
for ( Apple a : apples) {
if ( filter(a) ) result.add(a);
}
return result;
}
3.2使用匿名类来实现行为参数化,简化了实现类多的问题,但依然代码繁琐
interface ApplePredicate{
boolean filter(Apple apple);
}
public List<Apple> getApples(List<Apple> apples,
new ApplePredicate(){
public boolean filter(Apple apple) {}
}) {
List<Apple> result = new ArrayList<Apple>();
for ( Apple a : apples) {
if ( filter(a) ) result.add(a);
}
return result;
}
3.3使用lambda表达式,直接代码块参数化,简化了匿名类的繁琐,是java8之后最简洁的代码
interface ApplePredicate{
boolean filter(Apple apple);
}
public List<Apple> getApples(List<Apple> apples, a -> {....}) {
List<Apple> result = new ArrayList<Apple>();
for ( Apple a : apples) {
if ( filter(a) ) result.add(a);
}
return result;
}
需求变更:现在不比较苹果,变为香蕉、菠萝了呢?
4、泛型参数
interface ApplePredicate<T>{
boolean filter(T t);
}
public <T> List<T> getApples(List<T> apples, a -> {....}) {
List<T> result = new ArrayList<T>();
for ( T a : apples) {
if ( filter(a) ) result.add(a);
}
return result;
}