Java8实战 - 行为参数化传递代码
背景:
根据《java8实战》把第二章简单概括一下。
在软件工程中,一个最重要的问题是,用户的需求会一直变化,如何应对不断变化的需求,并且把工作量降到最低是需要考虑的,而行为参数化就是一个处理频繁变更需求的软件开发模式。
在我看来,行为参数化,是拿出一块代码段,准备好却不去执行,这个代码块会被其他部分调用,意味着可以推迟这个代码的执行。
下面用在库存中筛选苹果的案例来说明。
第一版:筛选绿苹果
public static List<Apple> filterGreenApples(List<Apple> inventory) {List<Apple> result = new ArrayList<>();for(Apple app: inventory) {if("green".equals(apple.getColor())) {result.add(apple);}}return result;
}
上面的代码可以就是筛选绿色苹果,但是如果现在需求变了,需要筛选红色苹果,那么第一反应是在上面的函数入参中,加入颜色条件来匹配。
第二版:颜色作为参数
public static List<Apple> filterGreenApples(List<Apple> inventory, String color) {List<Apple> result = new ArrayList<>();for(Apple app: inventory) {if(apple.getColor().equals(color)) {result.add(apple);}}return result;
}
List<Apple> greenApples = filterAppleByColor(Inventory, "green");
List<Apple> greenApples = filterAppleByColor(Inventory, "red");
这样可以得到最终答案,但是又出现了一个问题,现在需求变成需要能区分轻苹果和重苹果.
于是把上面代码拷贝一份又写了个针对重量的
第三版:重量作为参数
public static List<Apple> filterGreenApples(List<Apple> inventory, int weight) {List<Apple> result = new ArrayList<>();for(Apple app: inventory) {if(apple.getWeight() > weight) {result.add(apple);}}return result;
}
这样虽然可以,但是打破了DRY(Don't Repeat Yourself, 不要重复自己)软件工程原则,当然不重复情况下,还可以加上一个标志位来判断是对哪个条件进行查询,如下
第四版:颜色和重量统一查询函数
public static List<Apple> filterGreenApples(List<Apple> inventory, String color,int weight, boolean flag) {List<Apple> 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 List<Apple> filterApples(List<Apple> inventory, ApplePredicate p) {List<Apple> 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;}
}List<Apple> redAndHeavyApple = filterApples(inventory, new AppleRedAndHeavyPredicate());
但是这样还不完美,因为现在filterApples入参都需要一个new一个过滤条件相关的对象,并且实现test方法,为了在进一步减少代码,还可以用匿名类和lambda表达式
第六版:匿名类
List<Apple> redAndHeavyApple = filterApples(inventory, new AppleRedAndHeavyPredicate() {public boolean test(Apple apple) {return "red".equals(apple.getColor());}
});
匿名类看起来减少了类的实现代码,但是调用时候还是塞了很多代码。那么就到了最后一个
第七版:Lambda表达式
List<Apple> redAndHeavyApple = filterApples(inventory, (Apple apple) -> "red".equals(apple.getColor()));
这样看起来就干净多了。现在filterApples只是作用于苹果的筛选,我们甚至更进一步,造一个通用filter,用泛型来替代Apple,如下:
public interface Predicate<T> {boolean test(T t);
}public static <T> List<T> filter<List<T> list, Predicate<T> p> {List<T> result = new ArrayList<>();for(T e: list){if(p.test(e)){result.add(e);} }
}
这样就可以把filter方法用在香蕉,桔子,等等上。这边的Predicate<T>是一个函数式的接口,为了缩短篇幅,会在下个博客讲
相关文章:
Java8实战 - 行为参数化传递代码
背景: 根据《java8实战》把第二章简单概括一下。 在软件工程中,一个最重要的问题是,用户的需求会一直变化,如何应对不断变化的需求,并且把工作量降到最低是需要考虑的,而行为参数化就是一个处理频繁变更需…...
jmeter,取“临时重定向的登录接口”响应头中的cookie
1、线程组--创建线程组; 2、线程组--添加--取样器--HTTP请求; 3、Http请求--添加--后置处理器--正则表达式提取器; 4、线程组--添加--监听器--查看结果树; 5、线程组--添加--取样器--调试取样器。 首先理解 自动重定向 与跟随…...
流程控制之条件判断
目录 流程控制之条件判断 2.1.if语句语法 2.1.1单分支结构 2.1.2双分支结构 2.1.3多分支结构 2.2.案例 例一: 例2: 例3: 例4: 例5: 例6: 例7: 例8: 例9: 2.3.case多条件判断 2.3.1.格式 2.3.2.执行过程 例10: 流程控制之条件判断 2.1.if语句语法 2.1.1单分…...
2 - Electron 核心概念
Electron 核心概念 主进程 通过Node.js、Electron提供的API与系统底层打交道启动项目时运行的 main.js 脚本就是我们说的主进程。在主进程运行的脚本可以以创建 Web 页面的形式展示 GUI。主进程只有一个 渲染进程 每个 Electron 的页面都在运行着自己的进程,这样…...
Cmake找不到mysql.h和libmysqlclient.so
查看mysql.h和libmysqlclient.so的路径 eikeik-Virtual-Machine:~/桌面/dbpool/bin$ locate mysql.h /usr/include/mysql/mysql.h eikeik-Virtual-Machine:~/桌面/dbpool/bin$ locate libmysqlclient.so /usr/lib/x86_64-linux-gnu/libmysqlclient.so /usr/lib/x86_64-linux-g…...
图论——二分图
图论——二分图 二分图通俗解释 有一个图,将顶点分成两类,边只存在不同类顶点之间,同类顶点之间设有边。称图 G 为二部图,或称二分图,也称欧图。 性质 二分图不含有奇数环图中没有奇数环,一定可以转换为二…...
国产浪潮服务器:风扇免手动调节脚本
简介:浪潮集团,是中国本土顶尖的大型IT企业之一,中国领先的云计算、大数据服务商。浪潮集团旗下拥有浪潮信息、浪潮软件、浪潮国际,业务涵盖云计算、大数据、工业互联网等新一代信息技术产业领域,为全球120多个国家和地…...
智能科技企业网站搭建的作用是什么
随着科学技术快速提升,各种智能产品随之而来,每个赛道里都涌入了大量企业商家,有些热门产品更是广受关注,对企业来说,形象、品牌、信息等方面需要完美呈现到用户眼前,而网站无疑是很好的工具。 企业通过【…...
【多组学数据驱动的机器学习:生物医学研究的创新与突破】
简介:随着生物医学研究的不断发展,多组学数据在疾病预防、诊断和治疗方面发挥着越来越重要的作用。本文将介绍如何利用机器学习技术对多组学数据进行综合分析,以及这种方法在生物医学研究中的优势和潜力。 正文: 一、多组学数据…...
AI影响谷歌正在推出新的人工智能模型,用于医疗保健。以下是医生如何使用它们的介绍
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
云仓酒庄带您品法国葡萄酒
说起葡萄酒肯定绕不开法国,法国葡萄酒闻名中外,口碑卓越。作为世界上的产酒大国,可以说是每一寸土地都可以种植葡萄。云仓酒庄的品牌雷盛红酒分享这么优秀的一个葡萄酒产酒国有哪些特点呢? 1.产区特色:波国有最著名的…...
XIAO ESP32S3之实现口罩检测
一、例程介绍 此例程是运行FOMO 轻量检测模型实现人员佩戴口罩检测,Demo中已包含训练好的模型参数,无需再训练。 FOMO(Faster Objects, More Objects) 是由 Edgeimpulse 工程师提出的一种轻量级的目标检测模型,其主要特点是模型非常小&#…...
LVS简介及LVS-NAT负载均衡群集的搭建
目录 LVS群集简介 群集的含义和应用场景 性能扩展方式 群集的分类 负载均衡(LB) 高可用(HA) 高性能运算(HPC) LVS的三种工作模式 NAT 地址转换 TUN IP隧道 IP Tunnel DR 直接路由 Direct Rout…...
ElasticSearch之cat segments API
命令样例如下: curl -X GET "https://localhost:9200/_cat/segments?vtrue&pretty" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"执行结果输出如下: index shard prirep ip segment g…...
docker镜像与容器的迁移
docker容器迁移有两组命令,分别是 save & load :操作的是images, 所以要先把容器commit成镜像export & import:直接操作容器 我们先主要看看他们的区别: 一 把容器打包为镜像再迁移到其他服务器 如把mysq…...
Cmake基础(2)
使用一个简单的示例来应用cmake,无任何三方库的单一的应用程序项目 你可以收获 使用cmake生成VS项目生成mingw项目(makefile) 1 首先新建一个cpp,我们要做一个控制台应用程序 #include<iostream> void main(){std::cout<<"hello cm…...
OSPF理论总结与实验
第1章 OSPF[1] 本章阐述了OSPF协议的特征、术语,OSPF的路由器类型、网络类型、区域类型、LSA类型,OSPF报文的具体内容及作用,描述了OSPF的邻居关系,通过实例让读者掌握OSPF在各种场景中的配置。 本章包含以下内容: …...
浅谈安科瑞无线测温产品在巴西某工厂的应用
摘 要:高压开关设备是变电站和配电站中保证电力系统安全运行的重要设备之一,因此,开关柜的稳定运行对于整个电力系统有非常重要的意义。设备老化、长期高负荷运行都可能使设备局部温度过高而发生火灾,因此,对变电站内的敏感设备进行温度检测变得尤为重要…...
RabbitMQ 命令
Docker # 进入容器 > docker exec -it rabbitmq /bin/bash# 帮助 > rabbitmq-service help# 查看所有队列 > rabbitmqctl list_queues Windows 进入安装目录【D:\Program Files\RabbitMQ Server\rabbitmq_server-3.9.10\sbin】输入cmd # 帮助 > rabbitmq-servic…...
数据库系列之简要对比下GaussDB和OpenGauss数据库
GaussDB作为一款企业级的数据库产品,和开源数据库OpenGauss之间又是什么样的关系,刚开始接触的时候是一头雾水,因此本文简要对比下二者的区别,以加深了解。 1、GaussDB和OpenGauss数据库简要对比 GaussDB是华为基于PostgreSQL数据…...
FFmpeg的AVInputFormat
文章目录 结构体定义操作函数支持的AVOutputFormat 通过上面的分析,基本可以看到ffmpeg的套路了,首先一个context上下文,上下文里面一个priv_data 指针,然后再插件结构体中有一个priv_data_size,然后回调函数。 结构体…...
SQL命令---删除字段
介绍 使用sql语句删除表字段。 命令 alter table 表名 drop 字段名;例子 删除a表中的name字段。 alter table a drop name;下面是执行删除后的表结构:...
深入探讨 Python 中的装饰器和上下文管理器
Python 作为一门灵活而强大的语言,提供了许多高级特性,其中装饰器(Decorators)和上下文管理器(Context Managers)是其中两个非常有用的概念。这两个功能性特性提供了对代码结构和行为进行修改和控制的强大工…...
比whatsapp效果好---Google Messages RCS协议消息推送
这段时间由于使用谷歌手机Pixel 7 ( Android13)研究改机room,看了很多相关的资料,测试研究了谷歌生态很多软件功能。结果就是改机Room还没编译成功,反而是测试出Google Messages群发功能的bug,算是一个惊喜…...
HBuilder X
选择一款编程软件有以下几个好处: (1)提高效率:编程软件通常强调代码编辑和自动完成,可以帮助程序员更快速、更准确地输入代码。 (2)降低错误率:编程软件还可以检测代码中的错误&a…...
异地现场工控设备,如何实现远程配置、调试?
南京某企业专注于工业物联领域,在相关项目中往往会在各个点位部署基于Linux系统的中控主机,实现各类物联设备信息的采集、汇总。但是,由于各点位分散多地,且数量达到了上百个,虽然中控主机具备4G物联网接入能力&#x…...
C++报错:error C2238: 意外的标记位于“;”之前
报错信息如下: 编译遇见这样的错误信息主要有一下几种: 情况一: 多数情况下出现这种问题的原因是因为头文件重复包含:即头文件A包含了B,头文件B又包含了A,导致编译器在加载头文件时陷入死循环。 解决办法…...
五、Microsoft群集服务(MSCS)环境的搭建
一、【目的】 学会利用Windows Server布置群集环境。 二、【设备】 FreeNAS11.2,Windows Server 2019 三、【要求】 学会利用Windows Server布置群集环境,掌握处理问题的能力。 配置表: 节点公网IP(public)内网IP(private)群集IP(clust…...
通义千问 Qwen-72B-Chat在PAI-DSW的微调推理实践
01 引言 通义千问-72B(Qwen-72B)是阿里云研发的通义千问大模型系列的720亿参数规模模型。Qwen-72B的预训练数据类型多样、覆盖广泛,包括大量网络文本、专业书籍、代码等。Qwen-72B-Chat是在Qwen-72B的基础上,使用对齐机制打造的…...
web应用体系以及windows网络常见操作应用
本课程目标 1.Dos命令(必须掌握) 2.网络体系(笔试选择填空题) 3.搭建windows测试环境 一、Dos命令 1.DOS窗口启动 启动方式1.进入DOS页面:win+R,键入cmd 启动方式2.开始-运行--输入cmd-回车,此时将出现一个显示命令提示符的窗口,如下图 2、常见的Dos命令: 1、cd…...
香河网站建设/网站软件下载
转载于:https://www.cnblogs.com/panda88/p/6006372.html...
济南网站设计公司富/网站关键词优化排名软件
自定义学习率代码可以加快训练的速度,下面是代码的内容和学习率的截图。 import matplotlib.pyplot as plt def lrfn(epoch):LR_START 0.00001LR_MAX 0.00005 *8#* strategy.num_replicas_in_syncLR_MIN 0.00001LR_RAMPUP_EPOCHS 5LR_SUSTAIN_EPOCHS 5LR_EXP_…...
网站建设素材网/十大职业资格培训机构
我听到的一些发声 你们赚的钱已经可以了: 我一个发小是做土木工程的,上海大学博士,参与很多著名建筑的工程,但是从薪资上看,还不如一些稍微像样的公司的6年多的高级开发。为什么?这就是行业的红利…...
深圳网站设计很棒 乐云践新/广州seo学徒
nginx 配置静态页面 进入到 nginx 的默认配置文件的位置 cd /etc/nginx ll修改 nginx.conf 这个文件, 注释掉原有的 service 块的内容 这个用户名 需要修改为 root , 要不然后序的配置静态文件的位置的时候会 报 403 的错误, 直接访问不到文件 参考文档 https://blog.csdn.…...
页面紧急情况访问升级跳拿笔记/关键词优化系统
使用版本:VS20191-两种格式单行注释:// 描述信息注:通常放在一行代码的上方,或者一条语句的末尾,对该行代码说明多行注释:/* 描述信息 */注:通常放在一段代码的上方,对该段代码做整体说明2-注释…...
罗湖专业做网站公司/企业专业搜索引擎优化
转载一篇写的不错的用python flask实现Restapi 服务器的文章,照着一步步做下来也没什么问题 http://www.cnblogs.com/vovlie/p/4178077.html 更详细的使用和介绍在原文,有时间再来慢慢研究吧https://blog.miguelgrinberg.com/post/the-flask-mega-tutori…...