瓯北网站建设,建设网站价格,实体店线上线下运营模式,龙武工会网站怎么做背景#xff1a;
根据《java8实战》把第二章简单概括一下。
在软件工程中#xff0c;一个最重要的问题是#xff0c;用户的需求会一直变化#xff0c;如何应对不断变化的需求#xff0c;并且把工作量降到最低是需要考虑的#xff0c;而行为参数化就是一个处理频繁变更需…背景
根据《java8实战》把第二章简单概括一下。
在软件工程中一个最重要的问题是用户的需求会一直变化如何应对不断变化的需求并且把工作量降到最低是需要考虑的而行为参数化就是一个处理频繁变更需求的软件开发模式。
在我看来行为参数化是拿出一块代码段准备好却不去执行这个代码块会被其他部分调用意味着可以推迟这个代码的执行。
下面用在库存中筛选苹果的案例来说明。
第一版筛选绿苹果
public static ListApple filterGreenApples(ListApple inventory) {ListApple result new ArrayList();for(Apple app: inventory) {if(green.equals(apple.getColor())) {result.add(apple);}}return result;
}
上面的代码可以就是筛选绿色苹果但是如果现在需求变了需要筛选红色苹果那么第一反应是在上面的函数入参中加入颜色条件来匹配。
第二版颜色作为参数
public static ListApple filterGreenApples(ListApple inventory, String color) {ListApple result new ArrayList();for(Apple app: inventory) {if(apple.getColor().equals(color)) {result.add(apple);}}return result;
}
ListApple greenApples filterAppleByColor(Inventory, green);
ListApple greenApples filterAppleByColor(Inventory, red);这样可以得到最终答案但是又出现了一个问题现在需求变成需要能区分轻苹果和重苹果.
于是把上面代码拷贝一份又写了个针对重量的
第三版重量作为参数
public static ListApple filterGreenApples(ListApple inventory, int weight) {ListApple result new ArrayList();for(Apple app: inventory) {if(apple.getWeight() weight) {result.add(apple);}}return result;
}
这样虽然可以但是打破了DRYDont Repeat Yourself, 不要重复自己软件工程原则当然不重复情况下还可以加上一个标志位来判断是对哪个条件进行查询如下
第四版颜色和重量统一查询函数
public static ListApple filterGreenApples(ListApple inventory, String color,int weight, boolean flag) {ListApple result new ArrayList();for(Apple app: inventory) {if((flag apple.getColor().equals(color)) || (!flag apple.getWeight() weight)){result.add(apple);}}return result;
}
这样的代码可读性很差并且标志位现在只是颜色和重量如果再加查询条件比如产地形状等就无法满足需求了.
行为参数化传递代码
考虑将选择的标准进行建模比如绿色的吗重量超过150克吗来返回一个boolean值这种返回boolean值函数称为”谓词“定义一个接口来选择标准建模
public interface ApplePredicate{boolean test(Apple apple);
}
那么就可以又很多实现类了比如
public class AppleHeavyWeightPredicate implements ApplePredicate {public boolean test(Apple apple) {return apple.getWeight() 150;}
}public class AppleGreenColorPredicate implements ApplePredicate {public boolean test(Apple apple) {return green.equals(apple.getColor());}
}
把不同filter方法的不同行为封装起来称为“策略”然后再运行时选择一个算法这个算法族就是applePredicate。
第五版applePredicate改造后
public static ListApple filterApples(ListApple inventory, ApplePredicate p) {ListApple result new ArrayList();for(Apple app: inventory) {if(p.test(apple)){result.add(apple);}}return result;
}
这样使用灵活多了假设选择需求变了组合条件既要红苹果又要重量超过150克那么就再增加一个类实现ApplePredicate就行
public class AppleRedAndHeavyPredicate implements ApplePredicate {public boolean test(Apple apple) {return red.equals(apple.getColor()) apple.getWeight() 150;}
}ListApple redAndHeavyApple filterApples(inventory, new AppleRedAndHeavyPredicate()); 但是这样还不完美因为现在filterApples入参都需要一个new一个过滤条件相关的对象并且实现test方法为了在进一步减少代码还可以用匿名类和lambda表达式
第六版匿名类
ListApple redAndHeavyApple filterApples(inventory, new AppleRedAndHeavyPredicate() {public boolean test(Apple apple) {return red.equals(apple.getColor());}
});
匿名类看起来减少了类的实现代码但是调用时候还是塞了很多代码。那么就到了最后一个
第七版Lambda表达式
ListApple redAndHeavyApple filterApples(inventory, (Apple apple) - red.equals(apple.getColor()));
这样看起来就干净多了。现在filterApples只是作用于苹果的筛选我们甚至更进一步造一个通用filter用泛型来替代Apple如下
public interface PredicateT {boolean test(T t);
}public static T ListT filterListT list, PredicateT p {ListT result new ArrayList();for(T e: list){if(p.test(e)){result.add(e);} }
}
这样就可以把filter方法用在香蕉桔子等等上。这边的PredicateT是一个函数式的接口为了缩短篇幅会在下个博客讲