【23种设计模式】七种设计原则:理论与 Java 实践
文章目录
- 23 种设计模式之七种设计原则:理论与 Java 实践
- 一、单一职责原则(SRP - Single Responsibility Principle)
- (一)理论介绍
- (二)Java 实现示例
- (三)关键步骤
- (四)流程图
- 二、开闭原则(OCP - Open Closed Principle)
- (一)理论介绍
- (二)Java 实现示例
- (三)关键步骤
- (四)流程图
- 三、里氏替换原则(LSP - Liskov Substitution Principle)
- (一)理论介绍
- (二)Java 实现示例
- (三)关键步骤
- (四)流程图
- 四、依赖倒置原则(DIP - Dependency Inversion Principle)
- (一)理论介绍
- (二)Java 实现示例
- (三)关键步骤
- (四)流程图
- 五、接口隔离原则(ISP - Interface Segregation Principle)
- (一)理论介绍
- (二)Java 实现示例
- (三)关键步骤
- (四)流程图
- 六、迪米特法则(LoD - Law of Demeter)
- (一)理论介绍
- (二)Java 实现示例
- (三)关键步骤
- (四)流程图
- 七、组合复用原则(CRP - Composite Reuse Principle)
- (一)理论介绍
- (二)Java 实现示例
- (三)关键步骤
- (四)流程图
23 种设计模式之七种设计原则:理论与 Java 实践
一、单一职责原则(SRP - Single Responsibility Principle)
(一)理论介绍
单一职责原则规定一个类应该只有一个引起它变化的原因,即一个类只负责一项职责。如果一个类承担了过多的职责,那么这些职责之间的耦合度会很高,一旦某个职责发生变化,可能会影响到整个类的其他职责相关的功能,导致代码的可维护性和可扩展性变差。
(二)Java 实现示例
假设我们有一个类来处理用户信息的存储和用户密码的加密。按照单一职责原则,我们将其拆分为两个类。
- 用户信息存储类:
public class UserInfoStorage {private String username;private String email;public void saveUserInfo(String username, String email) {this.username = username;this.email = email;// 这里可以添加将用户信息存储到数据库或文件的代码System.out.println("保存用户信息:用户名 - " + username + ",邮箱 - " + email);}public String getUsername() {return username;}public String getEmail() {return email;}
}
- 用户密码加密类:
public class UserPasswordEncryption {public String encryptPassword(String password) {// 简单的加密示例,实际中可能更复杂return password + "encrypted";}
}
(三)关键步骤
- 首先确定类的主要职责,如
UserInfoStorage
专注于用户信息的存储操作,UserPasswordEncryption
专注于密码加密。 - 在需要存储用户信息时,调用
UserInfoStorage
的saveUserInfo
方法;在需要加密密码时,调用UserPasswordEncryption
的encryptPassword
方法。
(四)流程图
开始
|
|-- 需要存储用户信息
| |
| |-- 调用 UserInfoStorage.saveUserInfo 方法
| | |
| | |-- 执行存储用户信息操作
|
|-- 需要加密密码
| |
| |-- 调用 UserPasswordEncryption.encryptPassword 方法
| | |
| | |-- 执行密码加密操作
结束
二、开闭原则(OCP - Open Closed Principle)
(一)理论介绍
开闭原则指出软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着当有新的需求或功能变化时,应该通过扩展现有代码来实现,而不是直接修改已有的代码,这样可以减少对原有系统的影响,降低出错的风险,提高系统的稳定性和可维护性。
(二)Java 实现示例
以图形绘制为例,我们有一个绘制形状的接口,然后不同形状的类实现该接口。
- 图形绘制接口:
public interface Shape {void draw();
}
- 圆形绘制类:
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("绘制圆形");}
}
- 矩形绘制类:
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("绘制矩形");}
}
如果要添加新的形状,如三角形,我们只需创建一个新的类实现 Shape
接口,而无需修改已有的 Shape
接口和 Circle
、Rectangle
类。
public class Triangle implements Shape {@Overridepublic void draw() {System.out.println("绘制三角形");}
}
(三)关键步骤
- 定义抽象的接口或基类,如
Shape
接口。 - 具体的类实现该接口或继承基类,如
Circle
、Rectangle
等。 - 当有新需求时,创建新的类实现相同的接口或继承相同的基类进行扩展。
(四)流程图
开始
|
|-- 定义 Shape 接口
| |
| |-- Circle 类实现 Shape 接口
| | |
| | |-- 实现 draw 方法
| |
| |-- Rectangle 类实现 Shape 接口
| | |
| | |-- 实现 draw 方法
| |
| |-- 当添加新形状(如 Triangle)
| | |
| | |-- Triangle 类实现 Shape 接口
| | | |
| | | |-- 实现 draw 方法
结束
三、里氏替换原则(LSP - Liskov Substitution Principle)
(一)理论介绍
里氏替换原则表明子类型必须能够替换它们的父类型。这意味着在程序中任何使用父类型的地方,都应该能够透明地使用子类型对象,而不会导致程序的错误或异常行为。子类型应该在行为上与父类型保持一致,或者是父类型行为的扩展。
(二)Java 实现示例
假设有一个基类 Bird
,它有一个 fly
方法。
public class Bird {public void fly() {System.out.println("鸟在飞");}
}
然后有一个子类 Penguin
,企鹅虽然是鸟类,但它不会飞。按照里氏替换原则,我们可以对 Penguin
类进行如下处理:
public class Penguin extends Bird {@Overridepublic void fly() {// 企鹅不会飞,这里可以抛出异常或者给出提示System.out.println("企鹅不会飞");}
}
这样在使用 Bird
类型的地方,如果传入的是 Penguin
对象,程序也能正常运行,只是会有相应的提示或异常处理,而不会导致系统崩溃。
(三)关键步骤
- 首先定义父类及其方法,如
Bird
类的fly
方法。 - 子类继承父类,并根据自身特性重写父类方法,如
Penguin
类重写fly
方法时考虑自身不会飞的情况。 - 在使用父类对象的代码中,可以替换为子类对象进行测试和运行,确保程序的正确性。
(四)流程图
开始
|
|-- 定义 Bird 类及 fly 方法
| |
| |-- Penguin 类继承 Bird 类
| | |
| | |-- 重写 fly 方法
| |
| |-- 在使用 Bird 类对象的地方
| | |
| | |-- 替换为 Penguin 类对象进行测试
| | | |
| | | |-- 检查程序运行情况
结束
四、依赖倒置原则(DIP - Dependency Inversion Principle)
(一)理论介绍
依赖倒置原则强调高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。通过引入抽象层,可以降低模块之间的耦合度,提高系统的灵活性和可维护性,使得系统更容易进行扩展和修改。
(二)Java 实现示例
以一个简单的日志记录系统为例。
- 日志记录抽象接口:
public interface Logger {void log(String message);
}
- 控制台日志记录类(低层模块):
public class ConsoleLogger implements Logger {@Overridepublic void log(String message) {System.out.println("控制台日志:" + message);}
}
- 应用程序类(高层模块):
public class Application {private Logger logger;public Application(Logger logger) {this.logger = logger;}public void doSomething() {logger.log("应用程序执行了某个操作");}
}
这样,Application
类不依赖于具体的 ConsoleLogger
类,而是依赖于 Logger
抽象接口。如果以后要添加文件日志记录功能,只需要创建一个实现 Logger
接口的 FileLogger
类,然后在创建 Application
类时传入 FileLogger
对象即可。
(三)关键步骤
- 定义抽象接口或抽象类,如
Logger
接口。 - 具体的低层模块类实现该抽象,如
ConsoleLogger
类。 - 高层模块类通过构造函数或其他方式依赖于抽象,如
Application
类依赖Logger
接口,并在运行时传入具体的实现类对象。
(四)流程图
开始
|
|-- 定义 Logger 接口
| |
| |-- ConsoleLogger 类实现 Logger 接口
| | |
| | |-- 实现 log 方法
| |
| |-- Application 类依赖 Logger 接口
| | |
| | |-- 通过构造函数接收 Logger 对象
| | | |
| | | |-- 在 doSomething 方法中使用 Logger 对象进行日志记录
| |
| |-- 若添加 FileLogger 类
| | |
| | |-- FileLogger 类实现 Logger 接口
| | | |
| | | |-- 实现 log 方法
| | |
| | |-- 在创建 Application 类时传入 FileLogger 对象
结束
五、接口隔离原则(ISP - Interface Segregation Principle)
(一)理论介绍
接口隔离原则指出客户端不应该被迫依赖于它不使用的方法。一个类对另一个类的依赖应该建立在最小的接口上,而不是大而全的接口。这样可以避免因接口中包含过多不必要的方法而导致类之间的耦合度过高,当接口发生变化时,减少对不必要依赖该接口的类的影响。
(二)Java 实现示例
假设有一个 Shape
接口,它包含了计算面积和计算周长以及绘制形状的方法。
public interface Shape {double calculateArea();double calculatePerimeter();void draw();
}
对于一些只需要计算面积和周长的类,如 Circle
和 Rectangle
,绘制形状的方法可能是不必要的。我们可以将 Shape
接口拆分为两个更小的接口。
- 几何形状计算接口:
public interface GeometricShape {double calculateArea();double calculatePerimeter();
}
- 可绘制形状接口:
public interface DrawableShape {void draw();
}
然后 Circle
和 Rectangle
类可以只实现 GeometricShape
接口,而对于一些需要绘制的形状类可以同时实现 DrawableShape
接口和 GeometricShape
接口。
(三)关键步骤
- 分析接口中的方法,确定哪些方法是相关的,哪些是不相关的。
- 根据方法的相关性将大接口拆分为多个小接口,如将
Shape
接口拆分为GeometricShape
和DrawableShape
接口。 - 具体的类根据自身需求选择实现合适的小接口,如
Circle
类实现GeometricShape
接口。
(四)流程图
开始
|
|-- 分析 Shape 接口方法
| |
| |-- 拆分 Shape 接口为 GeometricShape 和 DrawableShape 接口
| | |
| | |-- Circle 类实现 GeometricShape 接口
| | | |
| | | |-- 实现 calculateArea 和 calculatePerimeter 方法
| | |
| | |-- 若有可绘制形状类
| | | |
| | | |-- 实现 DrawableShape 接口和 GeometricShape 接口
| | | | |
| | | | |-- 实现相应方法
结束
六、迪米特法则(LoD - Law of Demeter)
(一)理论介绍
迪米特法则也称为最少知识原则,它强调一个对象应该对其他对象有最少的了解,只和朋友通信,不和陌生人说话。一个类应该尽量减少对其他类的直接依赖,通过引入中间类或方法来降低类之间的耦合度,使得系统的结构更加清晰,易于维护和扩展。
(二)Java 实现示例
假设有一个 Order
类,它包含了 Customer
信息和 Product
信息。
public class Order {private Customer customer;private Product product;public Order(Customer customer, Product product) {this.customer = customer;this.product = product;}public double calculateTotalPrice() {// 这里不直接访问 Customer 类的内部信息,而是通过 Customer 类提供的方法获取相关信息return product.getPrice() * customer.getDiscountFactor();}
}
Customer
类提供了 getDiscountFactor
方法来返回折扣因子,而不是 Order
类直接访问 Customer
类的内部数据来计算总价。
(三)关键步骤
- 确定类之间的依赖关系,如
Order
类依赖Customer
类和Product
类。 - 对于被依赖类,提供合适的方法来返回其他类需要的信息,如
Customer
类的getDiscountFactor
方法。 - 依赖类通过调用被依赖类的方法来获取信息并进行相关操作,如
Order
类通过customer.getDiscountFactor()
获取折扣因子。
(四)流程图
开始
|
|-- Order 类依赖 Customer 类和 Product 类
| |
| |-- Customer 类提供 getDiscountFactor 方法
| |
| |-- Order 类调用 customer.getDiscountFactor() 和 product.getPrice() 方法
| | |
| | |-- 计算订单总价
结束
七、组合复用原则(CRP - Composite Reuse Principle)
(一)理论介绍
组合复用原则提倡优先使用组合或聚合关系来实现复用,而不是继承关系。组合或聚合可以使系统更加灵活,因为组合对象的内部实现可以独立变化,而不会影响到其他使用该组合对象的类。继承关系则相对固定,子类对父类有较强的依赖,父类的变化可能会影响到子类。
(二)Java 实现示例
假设有一个 Car
类,它可以包含 Engine
、Wheel
等部件。
public class Car {private Engine engine;private Wheel[] wheels;public Car(Engine engine, Wheel[] wheels) {this.engine = engine;this.wheels = wheels;}public void start() {engine.start();for (Wheel wheel : wheels) {wheel.rotate();}}
}
这里 Car
类通过组合 Engine
和 Wheel
类来实现功能,而不是继承某个 Vehicle
类并包含这些部件。如果 Engine
或 Wheel
类有改进或变化,只要它们的接口不变,Car
类不需要进行大量修改。
(三)关键步骤
- 确定需要复用的功能或部件,如
Car
类确定需要Engine
和Wheel
类的功能。 - 使用组合或聚合关系将这些部件组合到目标类中,如
Car
类通过构造函数接收Engine
和Wheel
类对象。 - 在目标类中调用组合对象的方法来实现自身功能,如
Car
类的start
方法调用Engine
的start
方法和Wheel
的rotate
方法。
(四)流程图
开始
|
|-- 确定 Car 类需要 Engine 和 Wheel 类功能
| |
| |-- 通过构造函数组合 Engine 和 Wheel 类对象到 Car 类
| | |
| | |-- 在 Car 类的 start 方法中
| | | |
| | | |-- 调用 Engine.start 方法和 Wheel.rotate 方法
结束
通过对这七种设计原则的理解和实践,在 Java 编程中能够设计出更加灵活、可维护和可扩展的软件系统,这些原则是构建高质量软件架构的重要基础,并且在 23 种设计模式中也多有体现和应用。
相关文章:
【23种设计模式】七种设计原则:理论与 Java 实践
文章目录 23 种设计模式之七种设计原则:理论与 Java 实践一、单一职责原则(SRP - Single Responsibility Principle)(一)理论介绍(二)Java 实现示例(三)关键步骤…...
数据库与数据库管理系统概述
title: 数据库与数据库管理系统概述 date: 2024/12/7 updated: 2024/12/7 author: cmdragon excerpt: 在信息化迅速发展的时代,数据已成为企业和组织的重要资产。数据库与数据库管理系统(DBMS)是高效存储、管理和利用数据的核心工具。本文首先定义了数据库的基本概念和特…...
42_GAN网络详解(2)---常见的GAN
DCGAN CGAN 条件生成对抗网络(Conditional Generative Adversarial Networks, CGAN)是生成对抗网络(Generative Adversarial Networks, GAN)的一种变体,由Mehdi Mirza和Simon Osindero在2014年提出。CGAN的主要改进在…...
目前国内【齿轮检测仪】行业整体较为分散,行业竞争日趋激烈
摘要 根据 HengCe (恒策咨询)的统计及预测,2023年全球齿轮检测仪市场销售额达到了6.2亿美元,预计2030年将达到9.4亿美元,年复合增长率(CAGR)为6.0%(2024-2030)。地区层面来看&#…...
【学习路线】Java
Java基础 基础 基础语法 面向对象 集合框架 JCF 进阶 并发编程 JVM 企业级开发 框架 Spring Boot Spring Cloud 分布式 高性能 高可用 安全 基建 Docker 实战 数据库 MySQL Redis 计算机基础 计算机组成原理 操作系统 计算机网络 数据结构与算法 设计模式 参考:…...
一文说清flink从编码到部署上线
引言:目前flink的文章比较多、杂,很少有一个文章,从一个简单的例子入手,说清楚从编码、构建、部署全流程是怎么样的。所以编写本文,自己做个记录备查同时跟大家分享一下。本文以简单的mysql cdc为例展开说明。 环境说明…...
dolphinScheduler 任务调度
#Using docker-compose to Start Server #下载:https://dlcdn.apache.org/dolphinscheduler/3.1.9/apache-dolphinscheduler-3.1.9-src.tar.gz $ DOLPHINSCHEDULER_VERSION3.1.9 $ tar -zxf apache-dolphinscheduler-"${DOLPHINSCHEDULER_VERSION}"-src.t…...
【opencv入门教程】14. 矩阵乘除运算
文章选自: 一、函数multiply、divide //乘法 CV_EXPORTS_W void multiply(InputArray src1, InputArray src2,OutputArray dst, double scale 1, int dtype -1); brief 计算两个数组的每个元素的按比例缩放乘积 note 当输出数组的深度为 CV_32S 时,…...
SpEL
SPEL(Spring Expression Language)是一个强大的 支持查询和操作对象的表达式语言 Spring:https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html#expressions 表达式语言支持以下功能 文本…...
【SpringMVC】参数传递 重定向与转发 REST风格
文章目录 参数传递重定向与转发REST风格 参数传递 ModelAndView:包含视图信息和模型数据信息 public ModelAndView index1(){// 返回页面ModelAndView modelAndView new ModelAndView("视图名");// 或// ModelAndView modelAndView new ModelAndView(…...
OD B卷【考勤信息】
题目 公司用一个字符串来表示员工的出勤信息: absent: 缺勤;late: 迟到;leaveearly: 早退;present: 正常上班 现在根据员工出勤信息,判断本次能否获得出勤奖,能获得出勤奖的条件如下:缺勤不超…...
CTF学习24.11.19[音频隐写]
MISC07[音频隐写] 隐写术 隐写术是一门关于信息隐藏的技巧与科学,所谓信息隐藏指的是不让除预期的接收者之外的任何人知晓信息的传递事件或者信息的内容。隐写术的英文叫做Steganography,来源于特里特米乌斯的一本讲述密码学与隐写术的著作Steganograp…...
万字长文解读深度学习——VQ-VAE和VQ-VAE-2
🌺历史文章列表🌺 深度学习——优化算法、激活函数、归一化、正则化 深度学习——权重初始化、评估指标、梯度消失和梯度爆炸 深度学习——前向传播与反向传播、神经网络(前馈神经网络与反馈神经网络)、常见算法概要汇总 万字长…...
电脑投屏到电脑:Windows,macOS及Linux系统可以相互投屏!
本篇其实是电脑远程投屏到另一台电脑的操作介绍。本篇文章的方法可用于Windows,macOS及Linux系统的相互投屏。 为了避免介绍过程中出现“这台电脑”投屏到“那台电脑”的混乱表述,假定当前屏幕投出端是Windows系统电脑,屏幕接收端是Linux系统…...
【JuMP.jl】埃尔米特矩阵半定规划
考虑一个埃尔米特矩阵的半定规划问题: 给定矩阵 P [ 1 i i − 1 ] P\left[\begin{matrix} 1 & i\\ i & -1 \end{matrix}\right] P[1ii−1] 计算 min X ⪰ 0 R e ( t r ( P H X ) ) \begin{aligned} \min_{X\succeq 0} Re(tr(P^HX)) \end{aligned}…...
MyCat(mysql的中间件)
文章目录 1 1...
Spring AI入门到精通:气象天气预测技术详解
引言 在全球气候变化的背景下,气象天气的准确预测对于农业、交通、能源等多个领域具有极其重要的意义。随着人工智能(AI)技术的飞速发展,特别是生成式AI和深度学习技术的突破,气象天气预测迎来了新的机遇。Spring AI&…...
ollama的本地部署内含推荐模型!
下载ollama 1.从官网(https://ollama.com/)下载ollama软件并且安装 注意软件是默认安装在C盘 打开cmd后输入:查看命令ollama --version 查看模型仓库:ollama list 显示模型信息: ollama show 在cmd中去拉模型: ollama pull 模…...
要使用 OpenResty 创建一个接口,返回客户端的 IP 地址,并以 JSON 格式输出
要使用 OpenResty 创建一个接口,返回客户端的 IP 地址,并以 JSON 格式输出 要使用 OpenResty 创建一个接口,返回客户端的 IP 地址,并以 JSON 格式输出方案一解决方案(openresty使用cjson)说明:使…...
排序的事
排序的事 C语言实现C实现Java实现Python实现 💐The Begin💐点点关注,收藏不迷路💐 输入n个不相同的正整数,每个数都不超过n。现在需要你把这些整数进行升序排序,每次可以交换两个数的位置,最少需…...
基于Matlab扩展卡尔曼滤波的GPS与DME组合无人机导航系统设计与实现
随着无人机(UAV)在农业监测、环境保护、物流运输、灾害救援等各个领域的广泛应用,精准且可靠的导航系统已成为提升无人机性能和任务执行能力的关键因素。传统的导航方法依赖于单一传感器,往往难以在复杂和动态的环境中提供足够的定…...
GEOBench-VLM:专为地理空间任务设计的视觉-语言模型基准测试数据集
2024-11-29 ,由穆罕默德本扎耶德人工智能大学等机构创建了GEOBench-VLM数据集,目的评估视觉-语言模型(VLM)在地理空间任务中的表现。该数据集的推出填补了现有基准测试在地理空间应用中的空白,提供了超过10,000个经过人工验证的指…...
重邮+数字信号处理实验三:z变换及离散LTI系统的z域分析
实验目的: ( 1 )学会运用 Matlab 求离散时间信号的有理函数 z 变换的部分分式展开; ( 2 )学会运用 Matlab 分析离散时间系统的系统函数的零极点; ( 3 )学会运用 …...
跟 Synchronized 相比,可重入锁 ReentrantLock 其实现原理有什么不同?
与Synchronized相比,可重入锁ReentrantLock在实现原理上存在显著差异。以下是对两者实现原理的详细比较: 一、基本机制 Synchronized: 是JVM基于监视器(Monitor)的实现,提供的内置锁。每个对象都有一个监…...
如何在 Cursor-AI 中配置 Conda 虚拟环境
如何在 CursorAI 中配置 Conda 虚拟环境并使用快捷键 引言 在数据科学和机器学习的开发过程中,使用虚拟环境来管理项目的依赖库是非常重要的。Conda 是一个常用的环境管理工具,它可以帮助我们创建和管理虚拟环境。在这篇博客中,我将介绍如何…...
carsim2020安装记录
step1:双击carsim安装包,进行正常安装, 参考连接:carsim安装流程 这里注意如何破解,踩了一晚上坑 step2:破解d 大体步骤为: 将param目录以及生成MSCLIC_SSQ.lic文件以及MADLIC_SSQ.lic文件,将这两个文件…...
前端开发底层逻辑全解析
前端开发就像是构建一座数字大厦的外表装饰与交互系统,而理解其底层逻辑则是打好坚实基础的关键。今天,我们就来深入剖析前端开发的底层逻辑。 一、浏览器的工作机制:幕后的魔法手 当我们在浏览器中打开一个网页时,一系列复杂的操…...
WSL2下如何部署CosyVoice并开启API服务
环境: WSL2 英伟达4070ti 12G Win10 Ubuntu22.04 问题描述: WSL下如何部署CosyVoice并开启API服务 解决方案: CosyVoice 下载不顺的时候,最好提前开科学 一、部署 1.拉取源码 git clone –recursive https://github.com/FunAudioLLM/CosyVoice.gitwsl下拉取 gi…...
操作系统Lesson8 - 同步互斥机制和编程方法
文章目录 忙等互斥与睡眠唤醒如何解决设立临界区 忙等互斥屏蔽中断可行性对单核处理系统上,最简单 锁变量严格轮询法Peterson算法问题代码:两个人互相谦让,造成死锁。解决方案 TSL指令 忙等互斥与睡眠唤醒 为了解决多个进程之间的操作不会相…...
OSGeo4W64和qtcreator环境配置
OSGeo4W64 release 64位,放在哪个盘都行 随便找个msvc64编译器 完整demo:OSGeo4W64和qtcreator 分享文件:osg4w64和qt.7z 链接:https://pan.xunlei.com/s/VODV85IkEKqQO88_QWNO_Be0A1# 提取码:8k8f 复制这段内容后打开…...
Ubuntu22部署MySQL5.7详细教程
Ubuntu22部署MySQL5.7详细教程 一、下载MySQL安装包二、安装MySQL三、启动MySQL 检查状态登录MySQL 四、开启远程访问功能 1、允许其他主机通过root访问数据库2、修改配置文件,允许其他IP通过自定义端口访问 五、使用Navicat连接数据库 默认情况下,Ubun…...
http和https分别是什么?区别是什么?
HTTP和HTTPS是两种常见的网络协议,用于在Web上进行数据传输。以下是它们的简要解释和主要区别: HTTP(Hypertext Transfer Protocol) HTTP是一种应用层协议,用于在Web上传输数据。它是互联网上应用最为广泛的一种网络…...
文件IO——01
1. 认识文件 1)文件概念 “文件”是一个广义的概念,可以代表很多东西 操作系统里,会把很多的硬件设备和软件资源抽象成“文件”,统一管理 但是大部分情况下的文件,都是指硬盘的文件(文件相当于是对“硬…...
23种设计模式之装饰模式
目录 1. 简介2. 代码2.1 ABatterCake (抽象组件)2.2 BatterCake (具体组件)2.3 ADecorator (抽象装饰者)2.4 EggDecorator (具体装饰者)2.5 SausageDecorator(具体装饰者…...
Ubuntu22.04系统源码编译OpenCV 4.10.0(包含opencv_contrib)
因项目需要使用不同版本的OpenCV,而本地的Ubuntu22.04系统装了ROS2自带OpenCV 4.5.4的版本,于是编译一个OpenCV 4.10.0(带opencv_contrib)版本,给特定的项目使用,这就不用换个设备后重新安装OpenCV 了&…...
《OpenCV:视觉世界的魔法钥匙》
《OpenCV:视觉世界的魔法钥匙》 一、OpenCV 是什么1. 起源与发展支持2. 特点与优势3. 编程语言支持 二、OpenCV 的发展历程1. 重要版本发布时间线2. 版本更新内容 三、OpenCV 的主要功能1. 图像处理2. 特征提取3. 目标检测4. 运动分析5. 人脸识别6. 其他功能 四、Op…...
Day7 苍穹外卖项目 缓存菜品、SpringCache框架、缓存套餐、添加购物车、查看购物车、清空购物车
目录 1.缓存菜品 1.1 问题说明 1.2 实现思路 1.3 代码开发 1.3.1 加入缓存 1.3.2 清除缓存 1.3.2.1 新增菜品优化 1.3.2.2 菜品批量删除优化 1.3.2.3 修改菜品优化 1.3.2.4 菜品起售停售优化 1.4 功能测试 1.4.1 加入缓存 1.4.2 菜品修改 1.5 代码提交 2.缓存套餐 2.1 Spring C…...
华为路由策略和策略路由学习笔记
控制网络流量可达性 思考:如何控制网络流量可达性? 解决方案一:可通过修改路由条目(即对接收和发布的路由进行过滤)来控制流量可达性,这种方式称为路由策略。 解决方案二:可直接通过依据用户制定的策略进行转发,且该策略优于路由…...
网上图书购物管理系统|Java|SSM|VUE| 前后端分离
【一】可以提供远程部署安装,包扩环境 【二】提供软件相关的安装包 【三】如果需要提供java入门资料可咨询 【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、M…...
杂发单的单据类型一个参数的逻辑
【核准中可改】被产线滥用了。它们可以这样做,开立一张杂发单,打印出来交领导层签名。单据要交财务做核算的。然后去修改杂发单的材料。以为可以瞒天过海。2个仓库,一个中掉坑里,一个发现了它们的拙劣的手段,上报之后没…...
AUTOSAR CP中基于通信模块(COM)的Transformer-R24的规范导读
该文档是关于 AUTOSAR CP中基于通信模块(COM)的Transformer的规范说明,主要内容包括引言、相关文档、约束与假设、功能规范、API 规范、配置规范等,旨在为汽车电子系统开发中基于 COM 的Transformer提供全面的技术规范和指导。 一…...
yarn : 无法加载文件 C:\Users\L\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁
关于执行安装yarn命令后执行yarn -v报错: 先确认执行安装yarn命令是否有误 # 安装yarn npm install yarn -g 终端输入set-ExecutionPolicy RemoteSigned 当然如果yarn -v仍然执行失败,考虑使用管理员方式运行IDEA, 注:如上操作…...
证明直纹面是可展曲面沿着直母线,曲面的切平面不变
目录 证明直纹面是可展曲面的当且仅当沿着直母线,曲面的切平面不变 证明直纹面是可展曲面的当且仅当沿着直母线,曲面的切平面不变 直纹面是可展曲面当且仅当沿着直母线,曲面的切平面不变. 证明:设直纹面 S S S的参数式为 r ( u …...
一种将png图像批量转换为RGB格式的方法
1.前言 大家在做2D图像分类的时候,代码经常要求图像是RGB格式。有时候我们的图像并不是RGB,尤其是处理病理图像切分的pach的时候,这时候就需要批量进行格式转换了。好了,直接上代码: import os from PIL import Image…...
Python 中的继承机制是什么样的?
Python的继承机制允许一个类(子类)继承另一个类(父类或基类)的属性和方法。 通过继承,可以实现代码复用,同时也能让代码结构更加清晰、易于维护。 Python支持单继承和多继承,并且有丰富的特性…...
MyBatis注解开发(一)
目录 使用注解完成CRUD 1. SqlMapConfig.xml配置文件 2. UserDao接口方法和注解的编写 3. UserTest测试方法的编写 注解方式比较简单,但是实际开发不推荐使用注解,使用配置文件的方式,不需要改源代码。 Insert:添加 Update:修改 Delete:删…...
挑战用React封装100个组件【010】
Hello,大家好,今天我挑战的组件是这样的! 今天这个组件是一个打卡成功,或者获得徽章后的组件。点击按钮后,会弹出礼花。项目中的勋章是我通过AI生成的,还是很厉害的哈!稍微抠图直接使用。最后面…...
深入浅出:Go语言中的错误处理
深入浅出:Go语言中的错误处理 引言 在任何编程语言中,错误处理都是一个至关重要的方面。它不仅影响程序的稳定性和可靠性,还决定了用户体验的质量。Go语言以其简洁明了的语法和强大的并发模型而著称,但其错误处理机制同样值得关…...
Spire.doc 合并word,复制word
之前使用的poi来实现这个功能,然后发现在复制chart时,边框样式无法修改,于是就使用了spire.doc 1. 引入依赖 <repositories><repository><id>com.e-iceblue</id><name>e-iceblue</name><url>https…...
《Java核心技术I》线程局部变量
线程局部变量 ThreadLocal辅助类为各个线程提供各自的实例。 public static final THreadLocal dateFormat ThreadLocal.withInitial(()->new SimpleDateFormat("yyyy-MM-dd")); 要访问具体的格式化方法,可以调用: String dateStamp d…...