【设计模式】装饰器模式 在java中的应用
文章目录
- 1. 引言
- 装饰器模式的定义与设计目的
- 装饰器模式与其他设计模式的比较
- 2. 装饰器模式的结构
- 组件接口(Component)
- 具体组件(ConcreteComponent)
- 装饰角色(Decorator)
- 具体装饰类(ConcreteDecorator)
- 3. 装饰器模式的实现
- Java代码示例:实现一个简单的文本消息处理
- 装饰角色(Decorator)
- 具体装饰类(ConcreteDecorator)
- 使用装饰器
- 4. 装饰器模式在Java标准库中的应用
- Java I/O库中的装饰器使用示例
- 分析`InputStream`, `OutputStream`, `Reader`, 和 `Writer`的装饰器实现
- 5. 装饰器模式的优缺点
- 优点
- 缺点
- 设计时的考虑因素
1. 引言
装饰器模式的定义与设计目的
装饰器模式(Decorator Pattern),也称为包装器(Wrapper),是一种结构型设计模式,它允许用户在不修改现有对象结构的情况下,向对象添加新的功能。这种模式通过创建一个包装对象来包裹真实对象,从而在保持原类方法签名完整性的前提下,提供额外的功能。
设计目的:
- 扩展功能:动态地添加功能到对象上,而不改变其结构。
- 替代子类化:在传统的继承关系中,功能的扩展通常通过创建子类实现。装饰器模式提供了一种灵活的替代方案,避免了类继承带来的复杂性和灵活性限制。
- 组合优于继承:装饰器模式使用对象的组合方式来扩展功能,这比继承更为灵活,易于维护和扩展。
装饰器模式与其他设计模式的比较
与代理模式的比较:
- 代理模式:
- 控制对另一个对象的访问。
- 不修改对象的行为,只是添加一层访问控制。
- 装饰器模式:
- 动态地添加功能。
- 直接影响对象的行为。
伪代码示例:
// 装饰器模式
interface Component {void execute();
}class ConcreteComponent implements Component {public void execute() {System.out.println("Execute original behavior");}
}class Decorator implements Component {private Component wrapped;Decorator(Component comp) {this.wrapped = comp;}public void execute() {wrapped.execute();addBehavior();}private void addBehavior() {System.out.println("Add additional behavior");}
}// 代理模式
interface Subject {void execute();
}class RealSubject implements Subject {public void execute() {System.out.println("Execute original behavior");}
}class Proxy implements Subject {private Subject realSubject;Proxy(Subject sub) {this.realSubject = sub;}public void execute() {System.out.println("Proxy control before execution");realSubject.execute();System.out.println("Proxy control after execution");}
}
与适配器模式的比较:
- 适配器模式:
- 使接口不兼容的对象能够一起工作。
- 不改变对象本身的行为,只是使其能够适应其他接口。
- 装饰器模式:
- 增加新的功能。
- 保持接口不变,而增加对象的职责。
伪代码示例:
// 装饰器模式
// 同上述装饰器示例// 适配器模式
interface Target {void newRequest();
}class Adaptee {public void oldRequest() {System.out.println("Old request execution");}
}class Adapter implements Target {private Adaptee adaptee;Adapter(Adaptee adaptee) {this.adaptee = adaptee;}public void newRequest() {adaptee.oldRequest();}
}
2. 装饰器模式的结构
装饰器模式主要包括以下四个角色:
组件接口(Component)
组件接口定义了一个对象接口,可以动态地添加责任(功能)到对象上。在Java中,这通常是一个接口或抽象类,为装饰的对象定义最基本的功能。
public interface Component {void operation();
}
具体组件(ConcreteComponent)
具体组件是被装饰的对象,实现或继承了组件接口。它定义了基本的功能,装饰器可以给这些功能添加额外的行为。
public class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("Basic operation of ConcreteComponent.");}
}
装饰角色(Decorator)
装饰角色持有一个组件(Component)对象的引用,并定义一个与组件接口一致的接口。这样它就可以将请求转发给组件对象,并可以在转发请求前后添加新的行为。
public abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {component.operation();}
}
具体装饰类(ConcreteDecorator)
具体装饰类是实现具体的装饰功能的类。它扩展了装饰角色,实现了在调用组件的方法前后可以执行额外的功能。
public class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}@Overridepublic void operation() {addedBehavior();super.operation();}private void addedBehavior() {System.out.println("Added behavior in ConcreteDecoratorA.");}
}public class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}@Overridepublic void operation() {super.operation();addedState();}private void addedState() {System.out.println("Added state in ConcreteDecoratorB.");}
}
这种结构允许你通过添加新的装饰类在运行时动态地扩展对象的功能,而不改变原有类的代码。这是一种非常灵活的方式来增加对象的职责,同时保持代码的可读性和可维护性。
3. 装饰器模式的实现
在本节中,我们将通过Java代码示例实现一个简单的文本消息处理应用,演示如何使用装饰器模式来添加新功能,如加密和过滤敏感词。
Java代码示例:实现一个简单的文本消息处理
首先,定义一个组件接口 Message
,它将具有一个方法 getContent()
来返回消息内容。
public interface Message {String getContent();
}
接下来,实现具体组件 TextMessage
,它实现了 Message
接口。
public class TextMessage implements Message {private String content;public TextMessage(String content) {this.content = content;}@Overridepublic String getContent() {return content;}
}
装饰角色(Decorator)
定义抽象装饰类 MessageDecorator
,它实现了 Message
接口,并持有一个 Message
对象的引用,以便对其进行装饰。
public abstract class MessageDecorator implements Message {protected Message message;public MessageDecorator(Message message) {this.message = message;}
}
具体装饰类(ConcreteDecorator)
- 加密装饰器 - 用于加密消息内容。
public class EncryptMessageDecorator extends MessageDecorator {public EncryptMessageDecorator(Message message) {super(message);}@Overridepublic String getContent() {return encryptContent(super.message.getContent());}private String encryptContent(String content) {// 简单的加密算法(示例用)return Base64.getEncoder().encodeToString(content.getBytes());}
}
- 敏感词过滤装饰器 - 用于过滤消息中的敏感词。
public class FilterMessageDecorator extends MessageDecorator {public FilterMessageDecorator(Message message) {super(message);}@Overridepublic String getContent() {return filterContent(super.message.getContent());}private String filterContent(String content) {// 简单的敏感词过滤return content.replaceAll("敏感词", "***");}
}
使用装饰器
现在,使用这些装饰器来处理文本消息:
public class DecoratorDemo {public static void main(String[] args) {Message message = new TextMessage("这是一个包含敏感词的消息");Message filteredMessage = new FilterMessageDecorator(message);Message encryptedMessage = new EncryptMessageDecorator(filteredMessage);System.out.println("原始消息: " + message.getContent());System.out.println("过滤后的消息: " + filteredMessage.getContent());System.out.println("加密后的消息: " + encryptedMessage.getContent());}
}
在这个例子中,我们首先创建了一个文本消息,然后通过一个过滤装饰器来过滤敏感词,接着通过一个加密装饰器来加密内容。这样,我们可以看到,装饰器模式使得功能扩展变得非常灵活和方便。
4. 装饰器模式在Java标准库中的应用
Java标准库中充分利用了装饰器模式,尤其是在其输入/输出(I/O)系统中。这一部分将探讨Java I/O库中装饰器模式的应用,并分析InputStream
、OutputStream
、Reader
和Writer
类的装饰器实现。
Java I/O库中的装饰器使用示例
Java I/O库设计了一系列的类,用于读写数据。基类InputStream
和OutputStream
分别为字节流的输入和输出提供基础功能。装饰器模式在这里的应用允许用户根据需求灵活地添加功能,如缓冲、数据转换等。
示例代码:
import java.io.*;public class IODemo {public static void main(String[] args) throws IOException {// 创建一个文件输入流InputStream is = new FileInputStream("example.txt");// 使用BufferedInputStream装饰文件输入流InputStream bis = new BufferedInputStream(is);// 读取数据int data = bis.read();while (data != -1) {System.out.print((char) data);data = bis.read();}// 关闭流bis.close();is.close();}
}
在这个例子中,BufferedInputStream
是一个装饰器,它为FileInputStream
提供了缓冲功能,从而提高了读取大文件的效率。
分析InputStream
, OutputStream
, Reader
, 和 Writer
的装饰器实现
-
InputStream
和OutputStream
:- 这些是所有字节流类的基类,提供了基本的数据读写功能。
- 装饰器类如
BufferedInputStream
,BufferedOutputStream
,DataInputStream
,DataOutputStream
等,为基本流添加了特定功能,如缓冲处理、读写基本类型数据等。
-
Reader
和Writer
:- 这些是所有字符流类的基类,用于读写字符数据。
- 装饰器类如
BufferedReader
,BufferedWriter
,InputStreamReader
,OutputStreamWriter
等,提供了类似的装饰功能,但专注于字符处理。
这些装饰器类遵循开闭原则,使得原有代码不需要修改,就可以引入新的功能,展示了装饰器模式的强大灵活性。通过这种方式,Java I/O库能够提供丰富而灵活的数据处理能力,满足不同场景的需求。
5. 装饰器模式的优缺点
装饰器模式是一种非常有用的设计模式,尤其是在需要扩展对象功能而不修改原有类代码的情况下。然而,像所有设计模式一样,它也有其优势和潜在的缺点。
优点
-
增强功能:
装饰器模式允许动态地添加或修改对象的行为。这意味着在运行时可以根据需要增加额外的功能,而不是在编译时硬编码。 -
动态扩展:
由于装饰器模式允许在运行时添加功能,因此提供了极大的灵活性,使得系统可以更加动态地适应变化的需求。 -
遵循开闭原则:
根据开闭原则,软件实体应当对扩展开放,对修改封闭。装饰器模式允许在不修改现有对象的情况下通过添加新的装饰类来扩展对象的功能,很好地遵循了这一原则。
缺点
-
复杂性增加:
使用装饰器模式可能会导致设计中类的数量增加,每个类都专注于特定的功能增强。这可能会使系统结构变得更复杂,尤其是对于新来的开发者来说,理解各个类之间的关系可能会比较困难。 -
多层装饰可能导致系统复杂:
当多个装饰被堆叠使用时,理解和维护这样的代码可能变得更加困难。每一层装饰都会增加调用栈的深度,而且在调试时可能会使问题的追踪变得更加复杂。 -
性能考虑:
在某些高性能场景下,装饰器模式可能会引入额外的性能开销。每次调用装饰过的方法时,都可能涉及多个方法调用,这可能会影响到关键任务的执行时间。
尽管装饰器模式带来了设计上的多个优点,但在选择使用时应当权衡这些优缺点,并考虑是否适合当前的应用场景。在系统设计初期,合理规划和设计可以帮助避免过度使用装饰器模式带来的复杂性。
设计时的考虑因素
-
明确装饰器和被装饰对象的界限:
- 确保装饰器只关注于添加功能,而不改变原有对象的核心职责。
- 被装饰对象应该能够在没有任何装饰的情况下独立运作。
-
保持装饰器的透明性:
- 装饰器应该实现与被装饰对象相同的接口,这样的设计使得客户代码在使用装饰后的对象时,不需要区分它是原始对象还是被装饰过的对象。
-
选择合适的装饰器:
- 在设计初期,考虑哪些功能是通过装饰器模式添加的最合适,避免过度使用装饰器,导致设计过于复杂。
相关文章:
【设计模式】装饰器模式 在java中的应用
文章目录 1. 引言装饰器模式的定义与设计目的装饰器模式与其他设计模式的比较 2. 装饰器模式的结构组件接口(Component)具体组件(ConcreteComponent)装饰角色(Decorator)具体装饰类(ConcreteDec…...
【kafka】生产者的同步发送和异步发送
Kafka 的生产者端提供了同步发送和异步发送两种方式,适合不同的使用场景和性能需求。 以下是两种发送模式的详细讲解: 同步发送 概念 同步发送是指生产者在发送一条消息后,会阻塞当前线程,等待 Kafka 返回发送结果(…...
8. Debian系统中显示屏免密码自动登录
本文介绍如何在Debian系统上,启动后,自动免密登录,不卡在登录界面。 1. 修改lightDM配置文件 嵌入式Debian系统采用lightDM显示管理器,所以,一般需要修改它的配置文件/etc/lightdm/lightdm.conf,找到[Seat…...
SpringBoot 开源停车场管理收费系统
一、下载项目文件 下载源码项目文件口令: 【前端小程序地址】(3.0):伏脂火器白泽知洞座/~6f8d356LNL~:/【后台管理地址】(3.0):伏脂火器仇恨篆洞座/~0f4a356Ks2~:/【岗亭端地址】(3.0):动作火器智汇堂多好/~dd69356K6r~:/复制口令…...
QT的ui界面显示不全问题(适应高分辨率屏幕)
//自动适应高分辨率 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);一、问题 电脑分辨率高,默认情况下,打开QT的ui界面,显示不全按钮内容 二、解决方案 如果自己的电脑分辨率较高,可以尝试以下方案:自…...
双向链表的模拟实现 —— LinkedList
MyLinkedList类 public class MyLinkedList {// 定义节点类static class Node {int val;Node prev;Node next;public Node() {}public Node(int val) {this.val val;}}// 定义头节点private Node head;// 定义尾结点private Node tail;// 头插public void headInsert(int val…...
速盾:高防cdn预热指定url就只刷新这个吗?
高防CDN预热是指在网站上线或更新之前,将网站内容缓存到CDN节点服务器上,以提高用户访问网站的速度和稳定性。通常,预热可以通过指定URL来进行,而不是刷新整个网站。 预热指定URL的好处是可以选择性地进行缓存刷新,而…...
JDK21新特性
目录 虚拟线程(JEP 444): 顺序集合(JEP 431): 字符串模板(JEP 430): 模式匹配的增强(JEP 440、441以及443): 结构化并发和作用域值…...
json学习
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,也易于机器解析和生成。它通常用于在服务器和客户端之间交换数据,特别是在 Web 应用中。 JSON 格式基于 JavaScript 对象表示法&#…...
005-mysql常用的名称
语言分类 DDL :数据定义语言 1、线上DDL语句在对表操作,是要锁元数据表的,此时所有的修改类的命令无法正常运行。 2、对大表在高峰期进行DDL操作,可以使用工具:pt-online-schema-change gh-ost 工具(8.0以…...
PostgreSQL和MySQL区别
PostgreSQL 和 MySQL 有以下一些主要区别: 一、功能特性 1. 数据类型支持 - PostgreSQL:支持丰富的数据类型,包括数组、JSON、JSONB、hstore(键值对存储)、范围类型等。例如,可以直接在数据库中存储和查…...
Android笔记(三十四):onCreate执行Handler.post在onResume后才能执行?
背景 偶然发现一个点,就是在onCreate执行Handler.post在onResume后才执行,以下是测试代码 多次运行的结果一致,为什么execute runnable不是在onCreate和onResume之间执行的呢,带着疑问撸了一遍Activity启动流程 关键源码分析 …...
动手学深度学习d2l包M4芯片 gpu加速
conda创建环境 CONDA_SUBDIRosx-arm64 conda create -n ml python3.9 -c conda-forge conda env config vars set CONDA_SUBDIRosx-arm64 conda activate mlpip安装包 pip install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/n…...
游戏引擎学习第35天
开场介绍 今天的任务是继续改进一个虚拟的瓦片地图系统,使其适合处理更大的世界。我们希望这个系统能管理大范围的游戏世界,其中包含按需存储的小区域。昨天,我们介绍了“内存区域”的概念,用于管理持久性存储。我们计划今天继续…...
Python 3 和 MongoDB 的集成使用
Python 3 和 MongoDB 的集成使用 MongoDB 是一个流行的 NoSQL 数据库,以其灵活的数据模型和强大的查询功能而闻名。Python 3 作为一种广泛使用的编程语言,与 MongoDB 的集成变得日益重要。本文将介绍如何在 Python 3 环境中集成和使用 MongoDBÿ…...
MperReduce学习笔记下
自定义InputFormat合并小文件 案例需求 无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案。 案例分析 小文件的优化无非以下几种方式: …...
react + antd desgin 使用form功能时upload,radio,checkbox不能回显的问题
最近使用react开发 遇到form回显的问题 ,处理upload回显的问题,提示 react-refresh:160 Warning: [antd: Upload] value is not a valid prop, do you mean fileList? 查看文档后,在form.item 组件下有一个特殊属性 valuePropName 子节点的值…...
【NLP修炼系列之Bert】Bert多分类多标签文本分类实战(附源码下载)
引言 今天我们就要用Bert做项目实战,实现文本多分类任务和我在实际公司业务中的多标签文本分类任务。通过本篇文章,可以让想实际入手Bert的NLP学习者迅速上手Bert实战项目。 1 项目介绍 本文是Bert文本多分类和多标签文本分类实战,其中多分…...
OpenSSL 自建CA 以及颁发证书(网站部署https双向认证)
前言 1、前面写过一篇 阿里云免费ssl证书申请与部署,大家可以去看下 2、建议大家看完本篇博客,可以再去了解 openssel 命令 openssl系列,写的很详细 一、openssl 安装说明 1、这部分就不再说了,我使用centos7.9,是自…...
YOLOv11改进,YOLOv11添加U-Netv2分割网络中SDI信息融合模块,助力小目标检测
摘要 理论介绍 SDI模块的架构: 平滑卷积(SmoothConv):用于平滑特征图,帮助减少噪声并使得特征更加稳定。Hadamard积:用于在特征图中进行逐元素相乘(点乘),以加强语义信息和细节信息的融合。通道注意力(ChannelAttention):利用通道注意力机制来自动关注重要的特征通…...
flex布局 flex-end为什么overflow无法滚动及解决方法
flex-end为什么overflow无法滚动及解决方法 在使用Flexbox布局时,我们经常使用justify-content和align-items属性来定位子元素。其中,align-items属性用于控制子元素在交叉轴上的位置,例如顶部对齐、底部对齐或居中对齐等。当我们将align-it…...
从ground_truth mask中获取图像的轮廓图
引言 在图像取证领域,主要分为检测和定位两个方面。检测就是判断一张图片是否为伪造图,定位与传统意义上的语义分割任务相近,就是定位伪造像素的区域。如果单纯使用语义分割网络训练,只能获得次优解,而像多任务学习那样…...
Java项目实战II基于微信小程序的旅游社交平台(开发文档+数据库+源码)
目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 随着移动互联网的迅猛发展,旅游已经成为人…...
开源即时通讯与闭源即时通讯该怎么选择,其优势是什么?
在选择即时通讯软件时,应根据企业的经营领域来选择适合自身需求的开源或闭源方案。不同领域对开源和闭源即时通讯的理念存在差异,因此总结两个点简要分析这两种选择,有助于做出更明智的决策。 一、开源与闭源的根本区别在于软件的源代码是否…...
【计算机网络】实验15:VLAN间通信的实现方法“单臂路由”
实验15 VLAN间通信的实现方法“单臂路由” 一、实验目的 加深对VLAN间通信的实现方法“单臂路由”的理解。 二、实验环境 Cisco Packet Tracer模拟器 三、实验过程 1.构建网络拓扑,并配置好主机的IP地址、子网掩码、默认网关,如图1,2所…...
数据库学习记录04
DDL【数据定义语言】 MySQL命名规则 数据库名不得超过30个字符,变量名限制为29个必须只能包含A-Z,a-z,0-9,_共63个字符不能在对象名的字符间留空格必须不能和用户定义的其他对象重名必须保证你的字段没有和保留字、数据库系统或常用方法冲突保持字段名和类型的一致…...
PDF文件打开之后不能打印,怎么解决?
正常的PDF文件是可以打印的,如果PDF文件打开之后发现文件不能打印,我们需要先查看一下自己的打印机是否能够正常运行,如果打印机是正常的,我们再查看一下,文件中的打印功能按钮是否是灰色的状态。 如果PDF中的大多数功…...
A* 算法 是什么?
A*(A-star)算法是一种启发式搜索算法,用于在图或网格中找到从起点到目标的最短路径。它被广泛用于路径规划问题,例如导航、游戏开发中的角色移动,以及机器人路径规划。 1. A 算法的基本概念* A* 算法结合了两种经典搜…...
ORM框架详解:为什么不直接写SQL?
想象一下,你正在开发一个小型的在线书店应用。你需要存储书籍信息、用户数据和订单记录。作为一个初学者,你可能会想:“我已经学会了SQL,为什么还要使用ORM框架呢?直接写SQL语句不是更简单、更直接吗?” 如…...
厘米级高精度RTK手持终端北斗卫星定位手持pda
RTK是一种测量技术叫“载波相位差分技术”,是实时处理两个测量站载波相位观测量的差分方法,将基准站采集的载波相位发给用户接收机,进行求差解算坐标,以此得到高精度坐标。随着技术的不断革新,GPS接收机也由原来只能用…...
Kafka-Connect源码分析
一、上下文 《Kafka-Connect自带示例》中我们尝试了零配置启动producer和consumer去生产和消费数据,那么它内部是如何实现的呢?下面我们从源码来揭开它神秘的面纱。 二、入口类有哪些? 从启动脚本(connect-standalone.sh&#…...
【STM32 Modbus编程】-作为主设备读取保持/输入寄存器
作为主设备读取保持/输入寄存器 文章目录 作为主设备读取保持/输入寄存器1、硬件准备与连接1.1 RS485模块介绍1.2 硬件配置与接线1.3 软件准备2、读保持寄存器2.1 主设备发送请求2.2 从设备响应请求2.3 主机接收数据3、读输入寄存器4、结果4.1 保持寄存器4.2 输入寄存器在前面的…...
Kubesphere上搭建redis集群
Kubesphere上搭建redis集群 版本:redis:6.2.3 1)挂载配置 redis.conf: cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-require-full-coverage no cluster-migration-barrier 1 appendonly yes …...
learn-(Uni-app)跨平台应用的框架
使用 Vue.js 开发所有前端应用的框架,开发者编写一份代码,可发布到iOS、Android、Web(包括微信小程序、百度小程序、支付宝小程序、字节跳动小程序、H5、App等)等多个平台。 跨平台:Uni-app 支持编译到iOS、Android、W…...
target_compile_definitions
这个接口给目标定义的宏,不能像C中定义的宏一样,尝试利用宏进行替换: cmake_minimum_required(VERSION 3.8) project(compile_definitions_pro)add_executable(main_exec src/main.cpp)set(SYSTEM_NAME "") if(CMAKE_SYSTEM_NAME S…...
浏览器同源策略、跨域、跨域请求,服务器处理没、跨域解决方案
目录 什么是同源策略什么是跨域发生跨域时,服务器有没有接到请求并处理响应:(两种情况) 如何解决跨域 什么是同源策略 概念: 同源策略是浏览器的一种安全机制,用于防止恶意网站对用户的敏感数据进行未经授…...
深入理解网络安全等级保护:保障信息安全的关键策略与实践
随着信息技术的飞速发展,网络安全问题日益凸显。为了应对这一挑战,网络安全等级保护制度应运而生,旨在确保不同等级的信息和信息系统的安全。本文将探讨网络安全等级保护的基本概念、重要性及其实践方法。 一、信息安全等级保护的基本概念 1…...
MySQL
InnoDB 引擎底层存储和缓存原理 到目前为止,MySQL 对于我们来说还是一个黑盒,我们只负责使用客户端发 送请求并等待服务器返回结果,表中的数据到底存到了哪里?以什么格式存放的? MySQL 是以什么方式来访问的这些数据&…...
新书速览|循序渐进Node.js企业级开发实践
《循序渐进Node.js企业级开发实践》 1 本书内容 《循序渐进Node.js企业级开发实践》结合作者多年一线开发实践,系统地介绍了Node.js技术栈及其在企业级开发中的应用。全书共分5部分,第1部分基础知识(第1~3章)…...
2024三掌柜赠书活动第三十五期:Redis 应用实例
目录 前言 Redis操作都会,却不知道怎么用? 关于《Redis 应用实例》 编辑推荐 内容简介 作者简介 图书目录 《Redis 应用实例》全书速览 拓展:Redis使用场景 实例1:缓存应用 场景描述 实现方法 具体代码示例 实例2&a…...
Android 第三方框架:RxJava:源码分析:观察者模式
文章目录 观察者模式RxJava中的观察者模式总结 观察者模式 RxJava中的观察者模式 以Observable、ObservableOnSubscribe、Observer为例 Observable是被观察者 负责发射事件或数据 Observer是观察器 负责对从被观察者中获取的数…...
开源模型应用落地-安全合规篇-用户输入价值观判断(四)
一、前言 在深度合规功能中,对用户输入内容的价值观判断具有重要意义。这一功能不仅仅是对信息合法性和合规性的简单审核,更是对信息背后隐含的伦理道德和社会责任的深刻洞察。通过对价值观的判断,系统能够识别可能引发不当影响或冲突的内容,从而为用户提供更安全、更和谐的…...
【js逆向专题】13.jsvmp补环境篇一
目录 一.了解jsvmp技术1. js虚拟机保护方案2.jsvmp实现原理3. 模拟jsvmp执行过程 二.环境检测1. 什么是环境检测2.案例讲解 三. 项目实战1. 案例11.逆向目标2. 项目分析1.补第一个referrer2. 调试技巧13. 调试技巧24. 补充sign5. 补 length6. 参数长短补充 3. 逆向结果 2. 案例…...
Java---每日小题
题目1-极大极小游戏 给你一个下标从 0 开始的整数数组 nums ,其长度是 2 的幂。 对 nums 执行下述算法: 设 n 等于 nums 的长度,如果 n 1 ,终止 算法过程。否则,创建 一个新的整数数组 newNums ,新数组长度…...
leetcode 23. 合并 K 个升序链表
给你一个链表数组,每个链表都已经按升序排列。 输入:lists [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 解释:链表数组如下: [1->4->5,1->3->4,2->6 ] 将它们合并到一个有序链表中得到。 1->…...
Windows 小记 6 -- 为什么我的全局消息钩子卸载不掉?
Hook dll 在其消息循环中被卸载。强制它们进入消息循环有助于卸载它们。在 UnhookWindowsHookEx 之后添加此代码以强制唤醒所有消息循环: DWORD dwResult; SendMessageTimeout(HWND_BROADCAST, WM_NULL, 0, 0, SMTO_ABORTIFHUNG|SMTO_NOTIMEOUTIFNOTHUNG, 1000, &a…...
Python+onlyoffice 实现在线word编辑
onlyoffice部署 version: "3" services:onlyoffice:image: onlyoffice/documentserver:7.5.1container_name: onlyofficerestart: alwaysenvironment:- JWT_ENABLEDfalse#- USE_UNAUTHORIZED_STORAGEtrue#- ONLYOFFICE_HTTPS_HSTS_ENABLEDfalseports:- "8080:8…...
LC低通滤波器Bode图分析(传递函数零极点)
LC低通滤波器 我们使得L4.7uH,C220uF;电感L的阻抗为Xl;电容C的阻抗为Xc; 传递函数 H ( s ) u o u i X C X C X L 1 s C 1 s C s L 1 1 s 2 L C (其中 s j ω ) H(s)\frac{u_{o} }{u_{i} } \frac{…...
【机器学习】机器学习的基本分类-无监督学习(Unsupervised Learning)
无监督学习(Unsupervised Learning) 无监督学习是一种机器学习方法,主要用于没有标签的数据集。其目标是从数据中挖掘出潜在的结构和模式。常见的无监督学习任务包括 聚类、降维、密度估计 和 异常检测。 1. 无监督学习的核心目标 1.1 聚类…...
六、docker compose单机容器编排工具
六、docker compose单机容器编排工具 6.1 compose简介 Compose是一个用于定义和运行多容器Docker应用程序的工具。您可以使用Compose文件来配置应用程序的服务,然后使用单个命令从配置中创建并启动所有服务。compose的配置文件示例如下 compose的github网址&#…...