行为参数化就是可以帮助你处理频繁变更需求的一种软件开发模式。
筛选苹果的例子:
Apple 类

@Getter
@Setter
public class Apple {private Integer weight;private String color;}

1.筛选出绿苹果

    public static List<Apple> filterGreenApples(List<Apple> inventory) {List<Apple> result = new ArrayList<Apple>();for(Apple apple: inventory){if( "green".equals(apple.getColor() ) {result.add(apple);}}return result;}

当满足了筛选绿苹果的需求后,用户可能会改变需求,需要筛选红苹果,浅绿色苹果等,所以我们需要在编写类似的代码之后尝试对其进行抽象,把颜色变成一个参数

public static List<Apple> filterApplesByColor(List<Apple> inventory,String color) {List<Apple> result = new ArrayList<Apple>();for (Apple apple: inventory){if ( apple.getColor().equals(color) ) {result.add(apple);}}return result;}

这样就能满足筛选不同颜色苹果的需求了。满足这个需求之后,农民可能会想,要是能筛选出重苹果或者轻苹果就好了,大于150g的为重苹果,于是就有

    public static List<Apple> filterApplesByWeight(List<Apple> inventory,int weight) {List<Apple> result = new ArrayList<Apple>();For (Apple apple: inventory){if ( apple.getWeight() > weight ){result.add(apple);}}return result;}

这样做虽然满足了需求,但是却复制了大部分代码,他们仅有下面两句代码不同

    if ( apple.getColor().equals(color) ) {result.add(apple);}if ( apple.getWeight() > weight ){result.add(apple);}

行为参数化

到这里,你可能会想到农民可能会根据苹果的产地,苹果的采摘时间等等各种不同属性来进行筛选,于是索性抽象出一个filterApples的方法。而筛选的条件无非就是根据苹果的各种属性进行判断,然后返回一个boolean值,于是我们抽象出ApplePredicate接口

    public interface ApplePredicate{boolean test (Apple apple);}

现在你就可以用ApplePredicate的多个实现代表不同的选择标准了

    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());}}

在这里我们抽象了ApplePredicate,每一种筛选就是一个策略,我们定义了筛选苹果的一族算法,把他们封装起来然后,然后在运行时选择一种算法,这就和策略模式相关联了。
经过抽象之后我们的filterApples方法是这样的

public static List<Apple> filterApples(List<Apple> inventory,ApplePredicate p){List<Apple> result = new ArrayList<>();for(Apple apple: inventory){if(p.test(apple)){ #筛选判断result.add(apple);}}return result;}

到这里,当农民又提出新的需求,比如想要筛选出大于150g的红苹果,那么只需要实现ApplePredicate接口,然后传入filterApples就能满足需求了,这比之前的方式要灵活很多。这时filterApples方法的行为取决于你通过ApplePredicate对像传递的代码,也就是我们filterApples方法的行为参数化了。
从上面的例子看比如筛选绿颜色苹果的类

    public class AppleGreenColorPredicate implements ApplePredicate{public boolean test(Apple apple){return "green".equals(apple.getColor());}}

其实我们只关心的是返回boolean值部分的代码

    "green".equals(apple.getColor());

而其他的代码都是实现一个接口的模板代码,都不是我们关心的,而通过lambda表达式我们就可以去掉那些臃肿的模板代码,像下面这样

    filterApples(inventory,apple -> "green".equals(apple.getColor()));

抽象升级

现在我们已经能够应对农民筛选苹果的需求了,但是当农民提出要对自家梨,橘子也有各种不同的筛选需求,此时我们不会有跟着将上面类似的代码写三遍,而是进行进一步的抽象,抽象成对一个列表根据不同条件进行筛选的方法,各种筛选条件就是不同的行为参数,于是就有了jdk里面stream的filter方法

Stream<T> filter(Predicate<? super T> predicate);

后面章节再介绍流
像上面的例子就可以写成

apples.stream().filter(apple -> "green".equals(apple.getColor()));

这段代码的意思是通过通过apples获得一个流,然后利用filter方法对苹果进行筛选。
类似于这样行为参数化的例子还有很多,他们结合lambda表达式会使得代码的编写变得更加简洁和优雅。通过抽象升级也使得代码更加灵活,易于扩展和维护,更加拥抱新的变化。

注:内容参考至《java8实战》扫描下方二维码关注微信公众号,输入java8sz下载该书。

转载于:https://www.cnblogs.com/vincili/p/9260681.html

(二)行为化参数传递代码相关推荐

  1. 【Zedboard】FPGA边缘提取 图像处理 基于ZYNQ完成 灰度图像 在VGA显示与 边缘提取 二值化 Verilog代码实现

    [Zedboard]FPGA边缘提取 图像处理 基于ZYNQ完成 灰度图像 在VGA显示与 边缘提取 二值化 Verilog代码实现 在项目开始到目前为止已经完成了在Zedboard的PL部分即FPG ...

  2. 使用深度学习解决拍照文档复杂背景二值化问题

    前言 1.在手持拍照设备对文档进行拍照时,很容易出现光线不均.阴影.过暗等,或者有些旧的文档,古籍文档都有虫洞.透背.字迹不清现象,为了方便阅读.打印文档,或者OCR识别,这些干扰都对处理结果有很多不 ...

  3. Opencv教程-图像二值化

    图像二值化的概念 图像二值化是指将指将256阶的灰度图通过合适的阈值,转换为黑白二值图.即像素或0和255.其目的通常为将图像的前后景进行分割,使图像变得简单,数据量减小,能凸显出感兴趣的目标的轮廓. ...

  4. Tusimple数据集生成二值化和实例化图片

    tusimple数据集下载的地址:here 数据集保存格式 |–dataset |----clips |----label_data_0313.json |----label_data_0531.js ...

  5. 图像二值化中阈值算法浅析

    目录 什么是二值化 常见的求阈值算法 OSTU大津法 概念及原理 iteration迭代法 概念及原理 代码实现 Sobel算子图像边缘提取 概念及原理 代码实现 噪点过滤 什么是二值化 所谓图像二值 ...

  6. 边缘识别+轮廓识别+边框+二值化

    机器视觉 图片处理 一:图片二值化 1. 什么是二值化 2. 代码 3. 结果展示 二:寻找物体轮廓 1. 主要函数 2. 代码 3.结果展示 三:二值化+边框 四:结语 边缘识别+轮廓识别+边框+二 ...

  7. 基于python的图像二值化处理(opencv)

    图像二值化处理 (python-opencv) 二值化 图像的二值化,在图像处理中是十分重要的一个步骤.是几乎所有后续的图像处理的基础和前提.只有根据不同场景选择不同的二值化处理,才能对一幅图片较好的 ...

  8. 图像处理之灰度图像转换与二值化

    灰度图像与二值化 问题描述:将彩色图像转换为灰度图像并进行二值化处理 代码如下(示例): #include <opencv2/opencv.hpp>cv::Mat BGR2GRAY(cv: ...

  9. 十三种基于直方图的图像全局二值化算法原理、实现、代码及效果(转)

    源:十三种基于直方图的图像全局二值化算法原理.实现.代码及效果.

最新文章

  1. hdu1042 java_N! hdu1042 | 学步园
  2. 如何让普通进程获得 root 的洪荒之力?
  3. python在中小学教学中的应用-小学信息技术教学中进行Python 编程语言教学的策略...
  4. JS 时间转化为几分钟前 几小时前 几天前
  5. 三星 Nexus S刷MIUI ROM最新图文刷机教程
  6. TensorRT学习笔记4 - 运行sampleGoogleNet
  7. DevOps运维开发一体化 - 公开课笔记
  8. Teams中的快捷键让沟通协作更加高效
  9. Hazelcast发布Jet 0.6版本
  10. Adobe illustrator 排版后图形导出这样的Tiff/PNG - 连载 3
  11. 【TensorFlow】TensorFlow从浅入深系列之十三 -- 教你深入理解模型持久化(模型保存、模型加载)
  12. (matlab)自定义图像(matlab)
  13. 设计灵感|简约复古风格海报设计这样玩
  14. OpenCV:概述、结构和内容
  15. eclipse迅速新建main函数
  16. mysql中的rman备份与恢复_使用RMAN备份与恢复数据库
  17. SNF开发平台WinForm-EasyQuery统计分析-效果-非常牛逼的报表查询工具
  18. poj 3295 Tautology 构造法
  19. 5万款Lr顶级调色预设合集,精心整理,分类清晰,摄影师调色师必备素材,够用一辈子
  20. vscode运行命令是报错:标记“”不是此版本中的有效语句分隔符。

热门文章

  1. c语言 结构成员 变量引用,C++结构体变量的引用
  2. CSS3之伪元素选择器和伪类选择器
  3. jsp中类似gridview的功能
  4. 引导界面(二)使用ViewPager实现欢迎引导页面
  5. 在Android开发中,有哪些好的内存优化方式?如何避免 Out Of Memory(OOM) ?
  6. linux内核引导时,从文件/etc/fstab 中读取要加载的文件系统
  7. 面试关于ISO七层模型你应该知道的东西
  8. 设计模式:享元模式(Flyweight Pattern)
  9. springmvc三: REST
  10. Spring Data JPA单元测试 Not a managed type