当前位置: 首页 > news >正文

Java8实战-总结33

Java8实战-总结33

  • 重构、测试和调试
    • 使用 Lambda 重构面向对象的设计模式
      • 策略模式
      • 模板方法

重构、测试和调试

使用 Lambda 重构面向对象的设计模式

新的语言特性常常让现存的编程模式或设计黯然失色。比如, Java 5中引入了for-each循环,由于它的稳健性和简洁性,已经替代了很多显式使用迭代器的情形。Java 7中推出的菱形操作符(<>)让大家在创建实例时无需显式使用泛型,一定程度上推动了Java程序员们采用类型接口(type interface)进行程序设计。

对设计经验的归纳总结被称为设计模式。设计软件时,可以复用这些方式方法来解决一些常见问题。这看起来像传统建筑工程师的工作方式,对典型的场景(比如悬挂桥、拱桥等)都定义有可重用的解决方案。例如,访问者模式常用于分离程序的算法和它的操作对象。单例模式一般用于限制类的实例化,仅生成一份对象。

Lambda表达式为程序员的工具箱又新添了一件利器。它们为解决传统设计模式所面对的问题提供了新的解决方案,不但如此,采用这些方案往往更高效、更简单。使用Lambda表达式后,很多现存的略显臃肿的面向对象设计模式能够用更精简的方式实现了。下面会针对五个设计模式展开讨论,分别是:

  • 策略模式
  • 模板方法
  • 观察者模式
  • 责任链模式
  • 工厂模式

策略模式

策略模式代表了解决一类算法的通用解决方案,可以在运行时选择使用哪种方案。例如使用不同的条件(比如苹果的重量,或者颜色)来筛选库存中的苹果。可以将这一模式应用到更广泛的领域,比如使用不同的标准来验证输入的有效性,使用不同的方式来分析或者格式化输入。
策略模式包含三部分内容:

  • 一个代表某个算法的接口(它是策略模式的接口)。
  • 一个或多个该接口的具体实现,它们代表了算法的多种实现(比如,实体类ConcreteStrategyA或者ConcreteStrategyB)。
  • 一个或多个使用策略对象的客户。
    在这里插入图片描述
    假设希望验证输入的内容是否根据标准进行了恰当的格式化(比如只包含小写字母或数字)。可以从定义一个验证文本(以String的形式表示)的接口入手:
public interface ValidationStrategy { boolean execute(String s); 
} 

其次,定义了该接口的一个或多个具体实现:

public class IsAllLowerCase implements ValidationStrategy { public boolean execute(String s) { return s.matches("[a-z]+"); } 
} 
public class IsNumeric implements ValidationStrategy { public boolean execute(String s) { return s.matches("\\d+"); } 
} 

之后,就可以在程序中使用这些略有差异的验证策略了:

public class Validator { private final ValidationStrategy strategy; public Validator(ValidationStrategy v) { this.strategy = v;} public boolean validate(String s) { return strategy.execute(s); } 
} Validator numericValidator = new Validator(new IsNumeric()); 
boolean b1 = numericValidator.validate("aaaa");  //返回false
Validator lowerCaseValidator = new Validator(new IsAllLowerCase()); 
boolean b2 = lowerCaseValidator.validate("bbbb");  //返回true

使用Lambda表达式
ValidationStrategy是一个函数接口(除此之外,它还与Predicate<String>具有同样的函数描述)。这意味着不需要声明新的类来实现不同的策略,通过直接传递Lambda表达式就能达到同样的目的,并且还更简洁:

Validator numericValidator = new Validator((String s) -> s.matches("[a-z]+")); 
boolean b1 = numericValidator.validate("aaaa");  //直接传递Lambda表达式
Validator lowerCaseValidator = new Validator((String s) -> s.matches("\\d+"));  //直接传递Lambda表达式
boolean b2 = lowerCaseValidator.validate("bbbb"); 

Lambda表达式避免了采用策略设计模式时僵化的模板代码。如果仔细分析一下个中缘由,会发现,Lambda表达式实际已经对部分代码(或策略)进行了封装,而这就是创建策略设计模式的初衷。因此,建议对类似的问题,应该尽量使用Lambda表达式来解决。

模板方法

如果需要采用某个算法的框架,同时又希望有一定的灵活度,能对它的某些部分进行改进,那么采用模板方法设计模式是比较通用的方案。换句话说,模板方法模式在你“希望使用这个算法,但是需要对其中的某些行进行改进,才能达到希望的效果”时是非常有用的。

从一个例子着手,看看这个模式是如何工作的。假设需要编写一个简单的在线银行应用。通常,用户需要输入一个用户账户,之后应用才能从银行的数据库中得到用户的详细信息,最终完成一些让用户满意的操作。不同分行的在线银行应用让客户满意的方式可能还略有不同,比如给客户的账户发放红利,或者仅仅是少发送一些推广文件。可能通过下面的抽象类方式来实现在线银行应用:

abstract class OnlineBanking { public void processCustomer(int id){ Customer c = Database.getCustomerWithId(id); makeCustomerHappy(c); }abstract void makeCustomerHappy(Customer c); 
} 

processCustomer方法搭建了在线银行算法的框架:获取客户提供的ID,然后提供服务让用户满意。不同的支行可以通过继承OnlineBanking类,对该方法提供差异化的实现。

使用Lambda表达式
使用Lambda表达式同样也可以解决这些问题(创建算法框架,让具体的实现插入某些部分)。你想要插入的不同算法组件可以通过Lambda表达式或者方法引用的方式实现。

这里向processCustomer方法引入了第二个参数,它是一个Consumer<Customer>类型的参数,与前文定义的makeCustomerHappy的特征保持一致:

public void processCustomer(int id, Consumer<Customer> makeCustomerHappy) { Customer c = Database.getCustomerWithId(id); makeCustomerHappy.accept(c); 
} 

现在,可以很方便地通过传递Lambda表达式,直接插入不同的行为,不再需要继承OnlineBanking类了:

new OnlineBankingLambda().processCustomer(1337, (Customer c) -> System.out.println("Hello " + c.getName()); 

相关文章:

Java8实战-总结33

Java8实战-总结33 重构、测试和调试使用 Lambda 重构面向对象的设计模式策略模式模板方法 重构、测试和调试 使用 Lambda 重构面向对象的设计模式 新的语言特性常常让现存的编程模式或设计黯然失色。比如&#xff0c; Java 5中引入了for-each循环&#xff0c;由于它的稳健性和…...

Postman 的使用教程(详细)

Postman 使用教程 1. 是什么 Postman 是一个接口测试工具软件&#xff0c;可以帮助开发人员管理测试接口。 官网&#xff1a;https://www.getpostman.com/ 2. 安装 建议通过官网下载安装&#xff0c;不要去那些乱七八糟的下载平台&#xff0c;或者留言获取 官网下载地址&am…...

单元测试 —— JUnit 5 参数化测试

JUnit 5参数化测试 目录 设置我们的第一个参数化测试参数来源 ValueSourceNullSource & EmptySourceMethodSourceCsvSourceCsvFileSourceEnumSourceArgumentsSource参数转换参数聚合奖励总结 如果您正在阅读这篇文章&#xff0c;说明您已经熟悉了JUnit。让我为您概括一下…...

uview组件库的安装

更多的请查看官方文档uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 (uviewui.com) // 如果您的根目录没有package.json文件的话&#xff0c;请先执行如下命令&#xff1a; // npm init -y 安装 npm install uview-ui2.0.36 // 更新 // npm update uvie…...

skywalking入门

参考&#xff1a; https://www.jianshu.com/p/ffa7ddcda4ab 参考&#xff1a; https://developer.aliyun.com/article/1201085 skywalking&#xff08;APM&#xff09; 调用链路分析以及应用监控分析工具 Skywalking主要由三大部分组成&#xff1a;agent、collector、webapp-…...

【Java 基础篇】Java多线程实现文件上传详解

文件上传是Web应用程序中常见的功能之一&#xff0c;用户可以通过网页将文件从本地计算机上传到服务器。在处理大文件或多用户并发上传的情况下&#xff0c;为了提高性能和用户体验&#xff0c;常常使用多线程来实现文件上传功能。本文将详细介绍如何使用Java多线程实现文件上传…...

【计算机基础】VS断点调试,边学边思考

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…...

BD就业复习第五天

1. 核心组件的优化&#xff1a;hive、spark、flink 针对Hive、Spark和Flink这三个核心组件&#xff0c;以下是它们的优化和一些常见面试题以及详细的回答&#xff1a; 1. Hive 优化 面试问题1&#xff1a;什么是Hive&#xff1f;为什么需要对Hive进行优化&#xff1f; 回答…...

ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the ‘ssl‘

报错&#xff1a; ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1, currently the ‘ssl’ module is compiled with OpenSSL 1.1.0h 27 Mar 2018.解决办法&#xff1a;将urllib3的版本降低 pip install urllib31.26.15参考 python包报错ImportError: urllib3 v2.…...

Qt5开发及实例V2.0-第十二章-Qt多线程

Qt5开发及实例V2.0-第十二章-Qt多线程 第12章 Qt 5多线程12.1 多线程及简单实例12.2 多线程控制12.2.1 互斥量12.2.2 信号量12.2.3 线程等待与唤醒 12.3 多线程应用12.3.1 【实例】&#xff1a;服务器编程12.3.2 【实例】&#xff1a;客户端编程 本章相关例程源码下载1.Qt5开发…...

Windows 修改系统默认字体

Windows Registry Editor Version 5.00; 重装机后电脑屏幕及字体调整.reg.lnk ;; 显示器分辨率: 3840*2160 ;; 自定义缩放: 266 ;; 辅助功能 - 文本大小 - 110% ;; 最后 ClearType 文本调谐器; https://www.cnblogs.com/bolang100/p/8548040.html#WINDOWS 10 显示中的仅更改文…...

图像处理软件Photoshop 2024 mac新增功能

Photoshop 2024 mac是一款图像处理软件的最新版本。ps2024提供了丰富的功能和工具&#xff0c;使用户能够对照片、插图、图形等进行精确的编辑和设计。 Photoshop 2024 mac软件特点 快速性能&#xff1a;Photoshop 2024 提供了更快的渲染速度和更高效的处理能力&#xff0c;让用…...

JavaScript之观察者模式

本文作者为 360 奇舞团前端开发工程师 概述 在日常开发中&#xff0c;开发人员经常使用设计模式来解决软件设计中的问题。其中&#xff0c;观察者模式是一种常用的模式&#xff0c;它可以帮助开发人员更好地处理对象之间的通信。在 JavaScript 中&#xff0c;观察者模式的应用非…...

深入了解ln命令:创建硬链接和符号链接的实用指南

文章目录 1. 引言1.1 关于ln命令1.2 ln命令的作用和用途 2. 基本用法2.1 创建硬链接2.2 创建符号链接2.3 区别硬链接和符号链接 3. 操作示例3.1 创建硬链接的示例3.2 创建符号链接的示例3.3 查看链接信息 4. 注意事项和常见问题4.1 文件路径4.2 软链接的相对路径4.3 软链接的更…...

虚拟IP技术

1.说明 虚拟IP&#xff08;Virtual IP Address&#xff0c;简称VIP&#xff09;是一个未分配给真实弹性云服务器网卡的IP地址。 弹性云服务器除了拥有私有IP地址外&#xff0c;还可以拥有虚拟IP地址&#xff0c;用户可以通过其中任意一个IP&#xff08;私有IP/虚拟IP&#xf…...

蓝桥杯 题库 简单 每日十题 day5

01 字符计数 字符计数 题目描述 给定一个单词&#xff0c;请计算这个单词中有多少个元音字母&#xff0c;多少个辅音字母。 元音字母包括a,e&#xff0c;i,o&#xff0c;u&#xff0c;共五个&#xff0c;其他均为辅音字母。 输入描述 输入格式&#xff1a; 输入一行&#xff0…...

【计算机网络】图解路由器(一)

图解路由器&#xff08;一&#xff09; 1、什么是路由器&#xff1f;2、什么是路由选择&#xff1f;3、什么是转发&#xff1f;4、路由器设备有哪些类型&#xff1f;5、根据性能分类&#xff0c;路由器有哪些类型&#xff1f;5.1 高端路由器5.2 中端路由器5.3 低端路由器 6、什…...

C语言文件的相关操作

C语言中文件的相关操作 文件的打开 使用文件的打开函数需要引入这个头文件&#xff1a;#include <fcntl.h> open函数 int open(char const *pathname, int flags, mode_t mode) 功能&#xff1a;打开已有的文件或者创建新文件参数 pathname&#xff1a;文件路径名&…...

Java入门级简单定时任务TimerTask

如果要执行一些简单的定时器任务&#xff0c;无须做复杂的控制&#xff0c;也无须保存状态&#xff0c;那么可以考虑使用JDK 入门级的定期器Timer来执行重复任务。 一、原理 JDK中&#xff0c;定时器任务的执行需要两个基本的类&#xff1a; java.util.Timer; java…...

Linux命令行教程:使用head和tail命令快速查看文件的开头和结尾

文章目录 简介A. 什么是head和tail命令B. head和tail命令的作用和用途 head命令A. 命令格式和语法B. 常见选项和参数1. -n&#xff1a;指定显示的行数2. -c&#xff1a;指定显示的字节数3. -v&#xff1a;显示文件名 C. 示例和应用实例1. 显示文件的前几行2. 显示多个文件的前几…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...

41道Django高频题整理(附答案背诵版)

解释一下 Django 和 Tornado 的关系&#xff1f; Django和Tornado都是Python的web框架&#xff0c;但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架&#xff0c;鼓励快速开发和干净、实用的设计。它遵循MVC设计&#xff0c;并强调代码复用。Django有…...

k8s从入门到放弃之Pod的容器探针检测

k8s从入门到放弃之Pod的容器探针检测 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;容器探测是指kubelet对容器执行定期诊断的过程&#xff0c;以确保容器中的应用程序处于预期的状态。这些探测是保障应用健康和高可用性的重要机制。Kubernetes提供了两种种类型…...

python读取SQLite表个并生成pdf文件

代码用于创建含50列的SQLite数据库并插入500行随机浮点数据&#xff0c;随后读取数据&#xff0c;通过ReportLab生成横向PDF表格&#xff0c;包含格式化&#xff08;两位小数&#xff09;及表头、网格线等美观样式。 # 导入所需库 import sqlite3 # 用于操作…...

CppCon 2015 学习:Simple, Extensible Pattern Matching in C++14

什么是 Pattern Matching&#xff08;模式匹配&#xff09; ❝ 模式匹配就是一种“描述式”的写法&#xff0c;不需要你手动判断、提取数据&#xff0c;而是直接描述你希望的数据结构是什么样子&#xff0c;系统自动判断并提取。❞ 你给的定义拆解&#xff1a; ✴ Instead of …...