责任链模式
07-责任链模式
1 导读
1.1 定义
包含了一些命令对象和一系列处理对象。每个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。
该模式还描述了往该处理链的末尾添加新的处理对象的方法。
精简定义:为请求创建一个接收此次请求对象的链。
1.2 类型
行为型。
2 适用场景
一个请求的处理需要多个对象当中的一或几个协作处理。
3 优点
请求的发送者和接收者(请求的处理)解耦,责任链可动态组合。
4 缺点
-
责任链太长或者处理时间过长,影响性能 -
责任链有可能过多
5 设计模式对比
5.1 V.S 状态模式
-
各对象并不指定下一个所要处理的对象者,只有在客户端类设置链顺序及元素,直到被某个责任链处理或整条链结束 -
每个状态知道自己下一个所要处理的对象者是谁,即编译时确定
6 实战
package com.javaedge.design.pattern.behavioral.chainofresponsibility;
import lombok.Getter;
import lombok.Setter;
/**
* @author JavaEdge
* @date 2019/1/19
*/
@Getter
@Setter
public class Course {
/**
* 课程名
*/
private String name;
/**
* 博客
*/
private String article;
/**
* 视频
*/
private String video;
}
package com.javaedge.design.pattern.behavioral.chainofresponsibility;
import org.apache.commons.lang3.StringUtils;
/**
* 【具体实现类】审批人
*
* @author JavaEdge
*/
public class ArticleApprover extends BaseApprover {
@Override
public void deploy(Course course) {
if (StringUtils.isNoneBlank(course.getArticle())) {
System.out.println(course.getName() + "含博客,批准!");
if (nextApprover != null) {
nextApprover.deploy(course);
}
} else {
System.out.println(course.getName() + "不含博客,拒绝!");
}
}
}
package com.javaedge.design.pattern.behavioral.chainofresponsibility;
/**
* 审批人
*
* @author JavaEdge
*/
public abstract class BaseApprover {
protected BaseApprover nextApprover;
public void setNextApprover(BaseApprover baseApprover) {
this.nextApprover = baseApprover;
}
/**
* 发布
*
* @param course 课程
*/
public abstract void deploy(Course course) ;
}
package com.javaedge.design.pattern.behavioral.chainofresponsibility;
import org.apache.commons.lang3.StringUtils;
import java.util.Objects;
/**
* 【具体实现类】审批人
*
* @author JavaEdge
*/
public class VideoApprover extends BaseApprover {
@Override
public void deploy(Course course) {
if (StringUtils.isNoneEmpty(course.getVideo())) {
System.out.println(course.getName() + "含视频,批准!");
if (Objects.nonNull(nextApprover)) {
nextApprover.deploy(course);
}
} else {
System.out.println(course.getName() + "不含视频,拒绝!");
}
}
}
UML:

测试类:
package com.javaedge.design.pattern.behavioral.chainofresponsibility;
/**
* @author JavaEdge
*/
public class Test {
public static void main(String[] args) {
BaseApprover articleApprover = new ArticleApprover();
BaseApprover videoApprover = new VideoApprover();
Course course = new Course();
course.setName("公众号-Learner");
course.setArticle("JavaEdge的博客");
course.setVideo("JavaEdge的小视频");
articleApprover.setNextApprover(videoApprover);
articleApprover.deploy(course);
}
}
output:
公众号-Learner含博客,批准!
公众号-Learner含视频,批准!
将博客注释掉:
public static void main(String[] args) {
BaseApprover articleApprover = new ArticleApprover();
BaseApprover videoApprover = new VideoApprover();
Course course = new Course();
course.setName("公众号-Learner");
// course.setArticle("JavaEdge的博客");
course.setVideo("JavaEdge的小视频");
articleApprover.setNextApprover(videoApprover);
articleApprover.deploy(course);
}
output:
公众号-Learner不含博客,拒绝!
7 框架应用
7.1 Tomcat#FilterChain
FilterChain 是一个由 Servlet 容器提供给开发人员的对象,提供一个对资源的过滤请求的调用链的视图。 过滤器使用 FilterChain 调用链中的下一个过滤器,或如果调用过滤器是链中的最后一个过滤器,则调用链末尾的资源
public interface FilterChain {
// 导致调用链中的下一个筛选器,或者如果调用筛选器是链中的最后一个筛选器,
// 则会导致调用链末尾的资源
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException;
}
8 项目实战
public final class AbstractChainContext<T> implements CommandLineRunner {
private final Map<String, List<AbstractChainHandler>> abstractChainHandlerContainer = Maps.newHashMap();
/**
* 责任链组件执行
*
* @param mark 责任链组件标识
* @param requestParam 请求参数
*/
public void handler(String mark, T requestParam) {
List<AbstractChainHandler> abstractChainHandlers = abstractChainHandlerContainer.get(mark);
if (CollectionUtils.isEmpty(abstractChainHandlers)) {
throw new RuntimeException(String.format("[%s] Chain of Responsibility ID is undefined.", mark));
}
abstractChainHandlers.forEach(each -> each.handler(requestParam));
}
@Override
public void run(String... args) throws Exception {
Map<String, AbstractChainHandler> chainFilterMap = ApplicationContextHolder
.getBeansOfType(AbstractChainHandler.class);
chainFilterMap.forEach((beanName, bean) -> {
List<AbstractChainHandler> abstractChainHandlers = abstractChainHandlerContainer.get(bean.mark());
if (CollectionUtils.isEmpty(abstractChainHandlers)) {
abstractChainHandlers = new ArrayList();
}
abstractChainHandlers.add(bean);
List<AbstractChainHandler> actualAbstractChainHandlers = abstractChainHandlers.stream()
.sorted(Comparator.comparing(Ordered::getOrder))
.collect(Collectors.toList());
abstractChainHandlerContainer.put(bean.mark(), actualAbstractChainHandlers);
});
}
}
抽取组件接口:
/**
* 抽象业务责任链组件
*
* @author JavaEdge
* @github <a href="https://github.com/Java-Edge" />
* @公众号 JavaEdge,关注回复:架构师,领取后端架构师成长手册
*/
public interface AbstractChainHandler<T> extends Ordered {
/**
* 执行责任链逻辑
*
* @param requestParam 责任链执行入参
*/
void handler(T requestParam);
/**
* @return 责任链组件标识
*/
String mark();
}
应用启动时加载所有责任链的组件,根据标识和order排序,保证执行顺序。
创建订单抽象出3个责任组件,分别order-0,-1,-2,标识为ORDER_CREATE_FILTER
/**
* 订单创建参数必填检验
*
* @author JavaEdge
* @github <a href="https://github.com/Java-Edge" />
* @公众号 JavaEdge,关注回复:架构师,领取后端架构师成长手册
*/
@Component
public final class OrderCreateParamNotNullChainHandler implements OrderCreateChainFilter<OrderCreateCommand> {
@Override
public void handler(OrderCreateCommand requestParam) {
if (Objects.isNull(requestParam.getCustomerUserId())) {
throw new ClientException(OrderCreateErrorCodeEnum.CUSTOMER_USER_ID_NOTNULL);
} else if (Objects.isNull(requestParam.getTotalAmount())) {
throw new ClientException(OrderCreateErrorCodeEnum.TOTAL_AMOUNT_NOTNULL);
} else if (Objects.isNull(requestParam.getPayAmount())) {
throw new ClientException(OrderCreateErrorCodeEnum.PAY_AMOUNT_NOTNULL);
} else if (Objects.isNull(requestParam.getFreightAmount())) {
throw new ClientException(OrderCreateErrorCodeEnum.FREIGHT_AMOUNT_NOTNULL);
} else if (Objects.isNull(requestParam.getSource())) {
throw new ClientException(OrderCreateErrorCodeEnum.SOURCE_NOTNULL);
}
}
@Override
public int getOrder() {
return 0;
}
}
/**
* 订单创建责任链过滤器
*
* @author JavaEdge
* @github <a href="https://github.com/Java-Edge" />
* @公众号 JavaEdge,关注回复:架构师,领取后端架构师成长手册
*/
public interface OrderCreateChainFilter<T extends OrderCreateCommand> extends AbstractChainHandler<OrderCreateCommand> {
@Override
default String mark() {
return OrderChainMarkEnum.ORDER_CREATE_FILTER.name();
}
}
最后执行:

泛型类
2.1 AbstractChainContext<T>
实现 CommandLineRunner 接口。它表示一个责任链上下文,用于执行责任链组件。
-
abstractChainHandlerContainer 是一个用于存储责任链组件的容器,使用 Map 数据结构来存储不同标识的责任链组件列表。每个标识对应一个责任链组件列表,列表中的责任链组件按照其顺序进行处理 -
handler 方法用于执行责任链组件。它接收一个标识 mark 和一个请求参数 requestParam,根据标识从容器中获取对应的责任链组件列表,并依次调用每个组件的 handler 方法进行处理 -
run 方法,通过 ApplicationContextHolder.getBeansOfType(AbstractChainHandler.class) 获取所有实现了 AbstractChainHandler 抽象类的 bean,然后遍历每个 bean,并将其添加到对应标识的责任链组件列表中。之后,对每个责任链组件列表进行排序,并更新到容器中
通过实现 CommandLineRunner 接口,该类可在 Spring Boot 应用程序启动时自动执行,并根据配置的责任链组件进行初始化和排序。之后,可以通过调用 handler 方法来执行责任链组件的处理逻辑。
2.2 抛出异常->执行中断
责任链模式中,当一个处理程序(或处理者)处理请求时,它可以选择继续将请求传递给下一个处理程序,也可以选择终止责任链的执行。
如果某个处理程序在处理请求时发生了异常,并且没有进行适当的处理或捕获该异常,那么该异常将向上级调用栈抛出,可能导致责任链的执行被中断。
在这种情况下,除非有适当的异常处理机制或错误处理策略来捕获和处理异常,否则可能会导致责任链的后续处理程序不会执行。
要确保在责任链中的处理程序发生异常时能够正确处理,建议在每个处理程序中使用适当的异常处理机制(例如 try-catch 块)来捕获和处理异常。这样可以防止异常在责任链中传播,并保证后续的处理程序能够继续执行。
获取更多干货内容,记得关注我哦。
本文由 mdnice 多平台发布
相关文章:
责任链模式
07-责任链模式 1 导读 1.1 定义 包含了一些命令对象和一系列处理对象。每个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。 该模式还描述了往该处理链的末尾添加新的处理对象的方法。 精简定义:为…...
2024.11.29(单链表)
思维导图 声明文件 #ifndef __LINKLIST_H__ #define __LINKLIST_H__#include <myhead.h>typedef char datatype; //数据元素类型 //定义节点类型 typedef struct Node {union{int len; //头节点数据域datatype data; //普通节点数据域};struct Node *next; //指针域…...
用Python做数据分析环境搭建及工具使用(Jupyter)
目录 一、Anaconda下载、安装 二、Jupyter 打开 三、Jupyter 常用快捷键 3.1 创建控制台 3.2 命令行模式下的快捷键 3.3 运行模式下快捷键 3.4 代码模式和笔记模式 3.5 编写Python代码 一、Anaconda下载、安装 【最新最全】Anaconda安装python环境_anaconda配置python…...
洛谷P1443 马的遍历
简单的bfs 题目链接 P1443 马的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述 有一个 nm 的棋盘,在某个点(x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。 输入格式 输入只有一行四个整数,分别为 n…...
实现一个Vue自定义指令
在 Vue 中,自定义指令允许你为 DOM 元素添加特定的行为或功能。下面是一个实现 Vue 自定义指令的简单示例,展示了如何创建一个指令,使得元素在鼠标悬停时改变背景色。 1. 创建自定义指令 在 Vue 2.x 中,你可以在 Vue.directive …...
【已解决】git push需要输入用户名和密码问题
解决方法: 1)查看使用的clone方式: git remote -v 2)若为HTTPS,删除原clone方式: git remote rm origin 3)添加新的clone方式: git remote add origin gitgithub.com:zludon/git_test.git …...
什么是内存对齐?为什么需要内存对齐?
1. 什么是内存对齐 内存对齐是指将数据存储在内存中时,按照一定的规则让数据排列在规定的地址上。具体来说,每个成员变量会按照其自身所占用的字节数对齐,内存首地址为对齐周期的倍数,而对齐周期指的是数据类型的大小。例如&…...
数据库操作、锁特性
1. DML、DDL和DQL是数据库操作语言的三种主要类型 1.1 DML(Data Manipulation Language)数据操纵语言 DML是用于检索、插入、更新和删除数据库中数据的SQL语句。 主要的DML语句包括: SELECT:用于查询数据库中的数据。 INSERT&a…...
xiaolin coding 图解网络笔记——TCP篇
1. TCP 头格式有哪些? 序列号:在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就【累加】一次该【数据字节数】的大小。用来解决网络包乱序问题。 确认应答号:指…...
基于大数据python 豆果美食推荐数据可视化系统(源码+LW+部署讲解+数据库+ppt)
!!!!!!!!! 很对人不知道选题怎么选 不清楚自己适合做哪块内容 都可以免费来问我 避免后期給自己答辩找麻烦 增加难度(部分学校只有一次答辩机会 没弄好就延迟…...
ElasticSearch通过es-head插件安装可视化及相关问题
1.es-head下载地址 GitHub - mobz/elasticsearch-head: A web front end for an elastic search cluster 2.启动 建议使用vscode启动,并安装好node.js环境 npm installnpm run start 通过http://localhost:9100就可以看到本地添加的es库 3.相关问题 3.1跨域问…...
JVM系列之OOM观测准备
OOM, 全称 “Out Of Memory”,即内存用完的意思。JVM 因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时(可分配内存大于需要分配的内存), 就会抛出 java.lang.OutOfMemoryError。在实际的生产应用中,一旦…...
基于Java Springboot Vue3图书管理系统
一、作品包含 源码数据库设计文档万字全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue3、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA 数据库&#x…...
解析生成对抗网络(GAN):原理与应用
目录 一、引言 二、生成对抗网络原理 (一)基本架构 (二)训练过程 三、生成对抗网络的应用 (一)图像生成 无条件图像生成: (二)数据增强 (三ÿ…...
torch.maximum函数介绍
torch.maximum 函数介绍 定义:torch.maximum(input, other) 返回两个张量的逐元素最大值。 输入参数: input: 张量,表示第一个输入。other: 张量或标量,表示第二个输入。若为张量,其形状需要能与 input 广播。输出&a…...
Git | 理解团队合作中Git分支的合并操作
合并操作 团队合作中Git分支的合并操作分支合并过程1.创建feature/A分支的过程2. 创建分支feature/A-COPY3.合并分支查看代码是否改变 团队合作中Git分支的合并操作 需求 假设团队项目中的主分支是main,团队成员A基于主分支main创建了feature/A,而我又在团队成员A创…...
源代码定制编译:构建理想的库 以curl为例
文章目录 源代码curl开发环境下载地址制定理想的库初级进阶如何知道选项名称交叉编译交叉编译工具链配置编译环境设置目标架构库和头文件路径编译代码 源代码 我们在日常中会接触到比较多第三方库,比如 网络库相关: libevent、mongoose、curl图形界面&…...
服务熔断-熔断器设计
文章目录 服务为什么需要熔断熔断器设计思想熔断器代码实现 服务为什么需要熔断 对于服务端采用的保护机制为服务限流。 对于服务调用端是否存在保护机制? 假如要发布一个服务 B,而服务 B 又依赖服务 C,当一个服务 A 来调用服务 B 时&#x…...
生产环境中:Flume 与 Prometheus 集成
在生产环境中,将 Apache Flume 与 Prometheus 集成的过程,需要借助 JMX Exporter 或 HTTP Exporter 来将 Flume 的监控数据转换为 Prometheus 格式。以下是详细的实现方法,连同原理和原因进行逐步解释,让刚接触的初学者也能完成集…...
深度解析MySQL的刷脏机制
前言 今天天气挺好,看大家对MySQL系列这么感兴趣,继续来聊聊MySQL,在MySQL的InnoDB中Buffer Pool和LSN关系紧密相连,尤其在脏页管理和刷新过程中起着至关重要的作用。理解LSN如何同Buffer Pool协同工作,有助于深入掌握 MySQL 的写入优化机制及数据一致性保证。 Buffer P…...
Java NIO 全面详解:初学者入门指南
除了前一篇文章讲的传统的 java.io 模块,Java 还提供了更现代化、更高效的非阻塞 IO 模块,即 java.nio(New IO)。java.nio 引入了面向缓冲区(Buffer)的数据处理方式,以及多路复用器(…...
优化 Conda 下载速度:详细的代理配置和网络管理策略
优化 Conda 下载速度:详细的代理配置和网络管理策略 为了彻底解决使用 Conda 下载 PyTorch 时遇到的速度问题,并确保下载过程稳定可靠,这需要一个详细、综合的技术方案。让我们更深入地分析问题原因,然后详尽地解释采取的解决策略…...
蓝牙MCU单片机8k高回报率无线应用
随着高端无线产品性能大幅提升,相比常规蓝牙133Hz回报率,8kHz回报率作为市场最高标准,每秒上传8000个数据包。以鼠标为例,位置每秒更新8000次,刷新率较常规蓝牙提升了60倍,超低延迟、极速响应,已…...
Java抛出自定义运行运行
1.重新生成异常的.java文件 Empty:空 Exception:异常 加起来就是 空指针异常的文件 2.打上extends 运行的异常(异常的类型) 3.点击ctrlo,选着这两个快捷重写 4.在需要抛出异常的地方写上:th…...
JVM 性能调优 -- JVM常用调优工具【jps、jstack、jmap、jstats 命令】
前言: 前面我们分析怎么去预估系统资源,怎么去设置 JVM 参数以及怎么去看 GC 日志,本篇我们分享一些常用的 JVM 调优工具,我们在进行 JVM 调优的时候,通常需要借助一些工具来对系统的进行相关分析,从而确定…...
python+django自动化部署日志采用WebSocket前端实时展示
一、开发环境搭建和配置 # channels是一个用于在Django中实现WebSocket、HTTP/2和其他异步协议的库。 pip install channels#channels-redis是一个用于在Django Channels中使用Redis作为后台存储的库。它可以用于处理#WebSocket连接的持久化和消息传递。 pip install channels…...
【Flink-scala】DataStream编程模型之窗口计算-触发器-驱逐器
DataStream API编程模型 1.【Flink-Scala】DataStream编程模型之数据源、数据转换、数据输出 2.【Flink-scala】DataStream编程模型之 窗口的划分-时间概念-窗口计算程序 文章目录 DataStream API编程模型前言1.触发器1.1 代码示例 2.驱逐器2.1 代码示例 总结 前言 本小节我想…...
毕昇入门学习
schemas.py 概述 这段代码主要定义了一系列基于 Pydantic 的数据模型(BaseModel),用于数据验证和序列化,通常用于构建 API(如使用 FastAPI)。这些模型涵盖了用户认证、聊天消息、知识库管理、模型配置等多…...
实时数据开发|Flink实现数据输出--DataSinks操作
哇哦,又是快乐周五!今天主管又又又请我们喝奶茶了,是乐乐茶的草莓新品。甜甜的草莓配上糯叽叽的麻薯,喝完好满足。这应该不是什么加班信号吧哈哈哈,不加不加周五要回家。 前几天被不同的bug缠身,今天终于正…...
详解网络代理模式:规则、全局与直连的应用与配置
“详解网络代理模式:规则、全局与直连的应用与配置” 当然,为了提供更深入的理解,让我们对每种代理模式进行更详尽的探讨,包括它们的内部工作机制、具体使用场景以及在实际应用中的优势和局限。 规则模式(Rule-based…...
Nacos部署和使用(服务注册与发现、配置中心)
1. docker部署nacos 参考: docker安装nacos-CSDN博客 2.注册中心原理 在微服务远程调用的过程中,包括两个角色: 服务提供者:提供接口供其它微服务访问,比如 A-service服务消费者:调用其它微服务提供的…...
医学机器学习:数据预处理、超参数调优与模型比较的实用分析
摘要 本文介绍了医学中的机器学习,重点阐述了数据预处理、超参数调优和模型比较的技术。在数据预处理方面,包括数据收集与整理、处理缺失值、特征工程等内容,以确保数据质量和可用性。超参数调优对模型性能至关重要,介绍了多种调…...
【大数据学习 | Spark-SQL】关于RDD、DataFrame、Dataset对象
1. 概念: RDD: 弹性分布式数据集; DataFrame: DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库中的二维表格。带有schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型…...
流媒体中ES流、PS流 、TS流怎么理解
在流媒体的领域中,ES流、PS流和TS流是视频和音频数据的不同封装格式。它们通常用于传输、存储和播放多媒体内容。让我们分别了解一下它们的定义和用途。 1. ES流(Elementary Stream) ES流(基本流)是最基本的视频或音…...
阿里云ECS服务器磁盘空间不足的几个文件
查看磁盘空间命令: df -h /mnt 清零 echo >nohup.out 磁盘空间不足的文件列表: 一、nohup.out:来自"nohup java -jar service.jar &"命令产生的文件,位置在服务jar所在目录 二、access.log:位于…...
pip 安装指定镜像源
pip 安装指定镜像源 使用 pip 安装时,可以通过指定镜像源来加速安装速度,尤其在网络状况不佳或需要访问国内镜像源的情况下。 常见的国内镜像源 清华大学: https://pypi.tuna.tsinghua.edu.cn/simple 阿里云: https://mirrors.aliyun.com/pypi/simple …...
java全栈day10--后端Web基础(基础知识)
引言:只要能通过浏览器访问的网站全是B/S架构,其中最常用的服务器就是Tomcat 在浏览器与服务器交互的时候采用的协议是HTTP协议 一、Tomcat服务器 1.1介绍 官网地址:Apache Tomcat - Welcome! 1.2基本使用(网上有安装教程,建议…...
GPT(Generative Pre-trained Transformer) 和 Transformer的比较
GPT(Generative Pre-trained Transformer) 和 Transformer 的比较 flyfish 1. Transformer 是一种模型架构 Transformer 是一种通用的神经网络架构,由 Vaswani 等人在论文 “Attention Is All You Need”(2017)中提…...
大数据营销
大数据营销是一个热门的大数据应用。对于多数企业而言,大数据营销的主要价值源于以下几个方面。 市场预测与决策分析支持 数据对市场预测及决策分析的支持,早就在数据分析与数据挖掘盛行的年代被提出过。沃尔玛著名的“啤酒与尿布”案例就是那个时候的杰…...
数据字典的实现与应用 —— 提高系统灵活性与维护效率的关键
目录 前言1. 数据字典的基本概念1.1 什么是数据字典1.2 数据字典的主要特点 2. 数据字典的优势2.1 提高代码复用性2.2 提升系统的灵活性2.3 方便非技术人员管理2.4 减少错误概率 3. 数据字典在若依中的实现3.1 若依框架简介3.2 数据字典的结构设计 4. 若依框架中数据字典的配置…...
Scrapy管道设置和数据保存
1.1 介绍部分: 文字提到常用的Web框架有Django和Flask,接下来将学习一个全球范围内流行的爬虫框架Scrapy。 1.2 内容部分: Scrapy的概念、作用和工作流程 Scrapy的入门使用 Scrapy构造并发送请求 Scrapy模拟登陆 Scrapy管道的使用 Scrapy中…...
Jenkins的使用
文章目录 一、Jenkins是什么\有什么用\与GitLab的对比二、Jenkins的安装与配置Jenkins的安装方式在Linux上安装Jenkins:在Windows上安装Jenkins:配置Jenkins: (可选)配置启动用户为root(一定要是root吗??…...
计算机基础 原码反码补码问题
整数的二进制的表示形式:其实有三种 原码:直接根据数值写出的二进制序列就是原码 反码:原码的符号位不变,其他位按位取反就是反码 补码:反码1,就是补码 负数:-1 以补码形式存放在内存 写出 -1…...
ORB-SLAM2 ----- LocalMapping::SearchInNeighbors()
文章目录 一、函数意义二、函数讲解三、函数代码四、本函数使用的匹配方法ORBmatcher::Fuse()1. 函数讲解2. 函数代码 四、总结 一、函数意义 本函数是用于地图点融合的函数,前面的函数生成了新的地图点,但这些地图点可能在前面的关键帧中已经生成过了&a…...
游戏引擎学习第27天
仓库:https://gitee.com/mrxiao_com/2d_game 欢迎 项目的开始是从零开始构建一款完整的游戏,完全不依赖任何库或引擎。这样做有两个主要原因:首先,因为这非常有趣;其次,因为它非常具有教育意义。了解游戏开发的低层次…...
【超全总结】深度学习分割模型的损失函数类别及应用场景
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...
基于HTML和CSS的校园网页设计与实现
摘要 随着计算机、互联网与通信技术的进步,Internet在人们的学习、工作和生活中的地位也变得越来越高,校园网站已经成为学校与学生,学生与学生之间交流沟通的重要平台,对同学了解学校内发生的各种事情起到了重要的作用。学校网站…...
深度学习基础02_损失函数BP算法(上)
目录 一、损失函数 1、线性回归损失函数 1.MAE损失 2.MSE损失 3.SmoothL1Loss 2、多分类损失函数--CrossEntropyLoss 3、二分类损失函数--BCELoss 4、总结 二、BP算法 1、前向传播 1.输入层(Input Layer)到隐藏层(Hidden Layer) 2.隐藏层(Hidden Layer)到输出层(Ou…...
Flutter:列表分页,上拉加载下拉刷新,在GetBuilder模板使用方式
GetBuilder模板使用方式参考上一节 本篇主要代码记录如何使用上拉加载下拉刷新, 接口请求和商品组件的代码不包括在内 pubspec.yaml装包 cupertino_icons: ^1.0.8# 分页 上拉加载,下拉刷新pull_to_refresh_flutter3: 2.0.2商品列表:controlle…...
使用eclipse构建SpringBoot项目
我这里用eclipse2018版本做演示,大家有需要的可以下载Eclipse Downloads | The Eclipse Foundation 1.打开eclipse,选择存放代码的位置 2.选择 file >> new >> project >> 选择springboot文件下的 spring starter project 2.这里选择N…...