Java8实战-总结34

news2024/12/27 11:04:55

Java8实战-总结34

  • 重构、测试和调试
    • 使用 Lambda 重构面向对象的设计模式
      • 观察者模式
      • 责任链模式

重构、测试和调试

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

观察者模式

观察者模式是一种比较常见的方案,某些事件发生时(比如状态转变),如果一个对象(通常称之为主题)需要自动地通知其他多个对象(称为观察者),就会采用该方案。创建图形用户界面(GUI)程序时,经常会使用该设计模式。这种情况下,在图形用户界面组件(比如按钮)上注册一系列的观察者。如果点击按钮,观察者就会收到通知,并随即执行某个特定的行为。 但是观察者模式并不局限于图形用户界面。比如,观察者设计模式也适用于股票交易的情形,多个券商可能都希望对某一支股票价格(主题)的变动做出响应。下图通过UML图解释了观察者模式。
在这里插入图片描述
Twitter这样的应用设计并实现一个定制化的通知系统。想法很简单:好几家报纸机构,比如《纽约时报》《卫报》以及《世界报》都订阅了新闻,他们希望当接收的新闻中包含他们感兴趣的关键字时,能得到特别通知。首先,需要一个观察者接口,它将不同的观察者聚合在一起。它仅有一个名为notify的方法,一旦接收到一条新的新闻,该方法就会被调用:

interface Observer { 
	void notify(String tweet); 
} 

现在,可以声明不同的观察者(比如,这里是三家不同的报纸机构),依据新闻中不同的关键字分别定义不同的行为:

class NYTimes implements Observer { 
	public void notify(String tweet) { 
		if(tweet != null && tweet.contains("money")) { 
 			System.out.println("Breaking news in NY! " + tweet); 
		} 
	} 
} 

class Guardian implements Observer { 
	public void notify(String tweet) { 
		if(tweet != null && tweet.contains("queen")) { 
			System.out.println("Yet another news in London... " + tweet); 
		} 
	} 
} 

class LeMonde implements Observer { 
	public void notify(String tweet) { 
		if(tweet != null && tweet.contains("wine")) { 
			System.out.println("Today cheese, wine and news! " + tweet); 
		} 
	} 
} 

最重要的部分是Subject,为它定义一个接口:

interface Subject { 
	void registerObserver(Observer o); 
	void notifyObservers(String tweet); 
} 

Subject使用registerObserver方法可以注册一个新的观察者,使用notifyObservers方法通知它的观察者一个新闻的到来。更进一步,实现Feed类:

class Feed implements Subject { 
	private final List<Observer> observers = new ArrayList<>(); 
	public void registerObserver(Observer o) { 
		this.observers.add(o); 
	} 
	
	public void notifyObservers(String tweet) { 
		observers.forEach(o -> o.notify(tweet)); 
	} 
}

这是一个非常直观的实现:Feed类在内部维护了一个观察者列表,一条新闻到达时,它就进行通知。

	Feed f = new Feed(); 
	f.registerObserver(new NYTimes()); 
	f.registerObserver(new Guardian()); 
	f.registerObserver(new LeMonde()); 
	f.notifyObservers("The queen said her favourite book is Java 8 in Action!"); 

上面示例中,《卫报》会特别关注这条新闻。
使用Lambda表达式
Observer接口的所有实现类都提供了一个方法:notify。新闻到达时,它们都只是对同一段代码封装执行。Lambda表达式的设计初衷就是要消除这样的僵化代码。使用Lambda表达式后,无需显式地实例化三个观察者对象,直接传递Lambda表达式表示需要执行的行为即可:

f.registerObserver((String tweet) -> { 
	if(tweet != null && tweet.contains("money")) { 
		System.out.println("Breaking news in NY! " + tweet); 
	} 
}); 

f.registerObserver((String tweet) -> { 
	if(tweet != null && tweet.contains("queen")) { 
		System.out.println("Yet another news in London... " + tweet); 
	} 
}); 

是否随时随地都可以使用Lambda表达式呢?答案是否定的!前文介绍的例子中,Lambda适配得很好,那是因为需要执行的动作都很简单,因此才能很方便地消除僵化代码。但是,观察者的逻辑有可能十分复杂,它们可能还持有状态,抑或定义了多个方法,诸如此类。在这些情形下,还是应该继续使用类的方式。

责任链模式

责任链模式是一种创建处理对象序列(比如操作序列)的通用方案。一个处理对象可能需要在完成一些工作之后,将结果传递给另一个对象,这个对象接着做一些工作,再转交给下一个处理对象,以此类推。

通常,这种模式是通过定义一个代表处理对象的抽象类来实现的,在抽象类中会定义一个字段来记录后续对象。一旦对象完成它的工作,处理对象就会将它的工作转交给它的后继。代码中,这段逻辑看起来是下面这样:

public abstract class ProcessingObject<T> { 

	protected ProcessingObject<T> successor; 
	public void setSuccessor(ProcessingObject<T> successor) { 
		this.successor = successor;
 	} 
 	
	public T handle(T input) { 
		T r = handleWork(input); 
		if(successor != null) { 
			return successor.handle(r); 
		} 
		return r; 
	} 

	abstract protected T handleWork(T input); 
} 

下图以UML的方式阐释了责任链模式。
在这里插入图片描述
handle方法提供了如何进行工作处理的框架。不同的处理对象可以通过继承ProcessingObject类,提供handleWork方法来进行创建。

下面看看如何使用该设计模式。可以创建两个处理对象,它们的功能是进行一些文本处理工作。

public class HeaderTextProcessing extends ProcessingObject<String> { 
	public String handleWork(String text) { 
		return "From Raoul, Mario and Alan: " + text; 
	} 
} 

public class SpellCheckerProcessing extends ProcessingObject<String> { 
	public String handleWork(String text) { 
		return text.replaceAll("labda", "lambda"); 
	} 
} 

现在你就可以将这两个处理对象结合起来,构造一个操作序列:

	ProcessingObject<String> p1 = new HeaderTextProcessing(); 
	ProcessingObject<String> p2 = new SpellCheckerProcessing(); 
	p1.setSuccessor(p2);//将两个处理对象链接起来
	String result = p1.handle("Aren't labdas really sexy?!!"); 
	System.out.println(result); //打印输出“From Raoul, Mario and Alan: Aren't lambdas really sexy?!!

使用Lambda表达式
可以将处理对象作为函数的一个实例,为了链接这些函数,需要使用andThen方法对其进行构造。

	UnaryOperator<String> headerProcessing = (String text) -> "From Raoul, Mario and Alan: " + text; //第一个处理对象
	
	UnaryOperator<String> spellCheckerProcessing = (String text) -> text.replaceAll("labda", "lambda");  //第二个处理对象
	
	Function<String, String> pipeline = headerProcessing.andThen(spellCheckerProcessing); //将两个方法结合起来,结果就是一个操作链
	
	String result = pipeline.apply("Aren't labdas really sexy?!!");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1038117.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java之转换流的详细解析

2. 转换流 2.1 字符编码和字符集 字符编码 计算机中储存的信息都是用二进制数表示的&#xff0c;而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。按照某种规则&#xff0c;将字符存储到计算机中&#xff0c;称为编码 。反之&#xff0c;将…

docker容器安装MongoDB数据库

一&#xff1a;MongoDB数据库 1.1 简介 MongoDB是一个开源、高性能、无模式的文档型数据库&#xff0c;当初的设计就是用于简化开发和方便扩展&#xff0c;是NoSQL数据库产品中的一种。是最 像关系型数据库&#xff08;MySQL&#xff09;的非关系型数据库。 它支持的数据结构…

封装一个高级查询组件

封装一个高级查询组件 背景一&#xff0c;前端相关代码二&#xff0c;后端相关代码三&#xff0c;呈现效果总结 背景 业务有个按照自定义选择组合查询条件&#xff0c;保存下来每次查询的时候使用的需求。查了一下项目里的代码没有现成的组件可以用&#xff0c;于是封装了一个 …

腾讯mini项目-【指标监控服务重构】2023-08-29

今日已办 Collector 指标聚合 由于没有找到 Prometheus 官方提供的可以聚合指定时间区间内的聚合函数&#xff0c;所以自己对接Prometheus的api来聚合指定容器的cpu_avg、cpu_99th、mem_avg 实现成功后对接小组成员测试完提供的时间序列和相关容器&#xff0c;将数据记录在表格…

相机One Shot标定

1 原理说明 原理部分网上其他文章[1][2]也已经说的比较明白了&#xff0c;这里不再赘述。 2 总体流程 参考论文作者开源的Matlab代码[3]和github上的C代码[4]进行说明&#xff08;不得不说还是Matlab代码更优雅&#xff09; 论文方法总体分两部&#xff0c;第一部是在画面中找…

李宏毅hw-9:Explainable ML

——欲速则不达&#xff0c;我已经很幸运了&#xff0c;只要珍惜这份幸运就好了&#xff0c;不必患得患失&#xff0c;慢慢来。 ----查漏补缺&#xff1a; 1.关于这个os.listdir的使用 2.从‘num_文件名.jpg’中提取出数值&#xff1a; 3.slic图像分割标记函数的作用&#xf…

【音视频流媒体】4、摄像头:分辨率、光圈|快门|感光度、焦距

文章目录 一、摄像头分辨率二、光圈、快门、感光度2.1 光圈2.1.1 外观2.1.2 光圈在相机中如何表示的2.1.3 对拍照的影响2.1.4 如何选择合适的光圈2.1.5 光圈在相机中如何设置 2.2 快门2.2.1 外观2.2.2 快门在相机中的表示2.2.3 快门对于拍照有什么影响2.2.4 选择合适的快门2.2.…

【C#】.Net基础语法一

目录 一、程序集信息 【1.1】Properties中AssemblyInfo文件 二、.Net程序的两次编译过程 三、.Net中命名空间和类 【3.1】引入命名空间 【3.2】修改默认的命名空间 【3.3】命名空间的总结 四、.Net中数据类型 【4.1】数值型 【4.2】非数值型 五、.Net中变量 【5.1】…

Selenium WebUI 自动化测试框架

框架结构 框架结构 框架基于 PO 模型进行设计&#xff0c;将页面元素与操作进行拆分&#xff0c;减少页面改动时的维护成本&#xff1b;同时使用 xsd 自定义 xml 标签&#xff0c;通过解析 xml 来驱动 selenium 进行执行&#xff0c;减少了一定的语言学习成本。 主要功能 基于…

[架构之路-221]:鸿蒙系统和安卓系统的比较:微内核VS宏内核, 分布式VS单体式

目录 一、鸿蒙系统和安卓系统的系统架构 1.1 鸿蒙系统的分层架构 1.2 安卓系统的分层架构 1.3 鸿蒙系统和安卓系统是操作系统吗&#xff1f; 二、鸿蒙系统和安卓系统的系统架构比较 2.1 它们与Linux操作系统的关系 2.2 架构比较 三、操作系统基础 3.1 微内核架构 3.2…

leetcode刷题 二维数组 八方向

题目描述 输入&#xff1a;board [[0,1,0],[0,0,1],[1,1,1],[0,0,0]] 输出&#xff1a;[[0,0,0],[1,0,1],[0,1,1],[0,1,0]] 题目分析:就是以二维数组某个元素为中心&#xff0c;寻找周围八个方向的元素&#xff0c;按照题目要求修改二维数组元素返回&#xff1b; 拷贝一份二…

FPGA板卡启动以及LED灯带调试

环境配置 软件&#xff1a; MobaXterm&#xff08;free版本即可&#xff09;下载教程参考&#xff1a; MobaXterm&#xff08;终端工具&#xff09;下载&安装&使用教程_蜗牛也不慢......的博客-CSDN博客 Win32 Disklmager 下载教程参考&#xff1a; 不分类工具&am…

Nature Communications | 张阳课题组:端到端深度学习实现高精度RNA结构预测

RNA分子是基因转录的主要执行者&#xff0c;也是细胞运作的隐形功臣。它们在基因表达调控、支架构建以及催化活性等多个生命过程中都扮演着关键角色。虽然RNA如此重要&#xff0c;但由于实验数据的缺乏&#xff0c;准确预测RNA 的三维空间结构仍然是目前计算生物学面临的重大挑…

HDMI之HDCP 2.3

Authentication and Key Exchange Without Stored Km With Stored Km HDCP2Version DDC时序 协议截图 Bit2为1,可知DUT设备支持HDCP 2.2及以上版本 RxStatus DDC时序 协议截图 <

C++ 类、方法的同一声明不同实现的方式

问题提出 头文件&#xff1a;声明CurrentTime类和PrintTime方法。 #ifndef CURRENT_TIME_H #define CURRENT_TIME_H class CurrentTime { public:void PrintTime(); }; #endifmain函数&#xff1a;创建CurrentTime对象&#xff0c;调用PrintTime。 #include "current_t…

UNet网络模型:数据集制作

UNet网络模型&#xff1a;数据集制作 一般语义分割的原始图片和标记图片在以下目录下&#xff1a; SegmentationClass&#xff1a;标记图片。 JPEGImages&#xff1a;原始图片。 数据集往往都是很多的图片等信息&#xff0c;对于数据集类来说&#xff0c;一个类里有所有数据…

腾讯mini项目-【指标监控服务重构-会议记录】2023-07-06

7/6 会议记录 Profile4个步骤 解压kafka消息初始化性能事件&#xff0c;分析事件将数据写入kafkaRun 开始执行各stage handler 上报耗时到otel-collector。。。 // ConsumerDispatchHandler consumer // // param msg *sarama.ConsumerMessage // param consumer *databus.K…

FPGA project : rom_vga_jump

只有vga_pix 模块代码与rom_vga不同&#xff0c;所以只上传了这个模块的代码与仿真代码。 // #define BLACK 0x0000 // 黑色 // #define NAVY 0x000F // 深蓝色 // #define DGREEN 0x03E0 // 深绿色 // #define DCYAN …

Linux系统下安装Mysql

1、执行命令&#xff1a;rpm -qa | grep -i mysql&#xff0c;先查看系统之前是否有安装相关的rpm包&#xff0c;如果有&#xff0c;会显示类似下面的信息&#xff1b; 2、通过命令yum -y remove mysql-*  一次性删除系统上所有相关的rpm包&#xff0c;或者通过命令yum -y …

zemax显微镜设计

光学显微镜&#xff08;Optical Microscope&#xff0c;简写OM&#xff09;是利用光学原理&#xff0c;把人眼所不能分辨的微小物体放大成像&#xff0c;以供人们提取微细结构信息的光学仪器&#xff0c;第一架复式光学显微镜是于1665年由英国物理学家虎克制作。 首先做物镜 入…