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

【设计模式系列】装饰器模式

目录

一、什么是装饰器模式

二、装饰器模式中的角色

三、装饰器模式的典型应用场景

四、装饰器模式在BufferedReader中的应用


一、什么是装饰器模式

装饰器模式是一种结构型设计模式,用于在不修改对象自身的基础上,通过创建一个或多个装饰类来给对象动态地添加功能。这种模式提供了一种灵活的替代继承的方法,可以在运行时根据需要添加或去除对象的功能。

二、装饰器模式中的角色

  • Component(抽象构件)

    • 定义了对象的接口,可以给这些对象动态地添加功能。
    • 它是所有具体构件和装饰类的父类,声明了在装饰前对象的行为。
  • ConcreteComponent(具体构件)

    • 实现了 Component 接口,定义了将要接收附加责任的对象。
  • Decorator(抽象装饰类)

    • 它也有一个引用成员,该成员是指向着 Component 类型的。
    • 在装饰类中,可以定义一个方法用来调用在 ConcreteComponent 中实现的方法,同时也可以在修改或扩展 ConcreteComponent 的行为时添加新的功能。
  • ConcreteDecorator(具体装饰类)

    • 负责给构件对象添加新的功能。
    • 每一个具体装饰类都实现一个装饰器类,它们不是继承具体构件类,而是封装具体构件类的对象。

三、装饰器模式的典型应用场景

  1. 扩展系统功能: 在系统开发过程中,随着新需求的出现,可能需要为现有类添加新的功能。装饰器模式可以在不修改原有类代码的情况下,通过动态组合的方式增加功能。

  2. 动态添加行为: 在运行时根据不同的条件为对象动态添加行为,例如,根据用户的角色或权限动态地为用户界面添加或移除功能。

  3. 缓存机制: 在访问资源密集型对象(如数据库连接、文件系统等)时,可以使用装饰器模式实现缓存功能,以提高性能。

  4. 日志记录和性能监测: 在方法执行前后添加日志记录或性能监测代码,而不需要修改方法本身的实现,装饰器模式可以很方便地实现这一点。

四、装饰器模式在BufferedReader中的应用

BufferedReader 是 Java I/O 库中的一个类,它使用装饰器模式来提供缓冲的字符输入流功能。下面是 BufferedReader 如何应用装饰器模式的详细解释:

  1. 抽象构件(Component)

    • Reader 接口是抽象构件,它定义了读取字符的方法,如 read() 和 readLine()
  2. 具体构件(ConcreteComponent)

    • 类似于 FileReader 或 InputStreamReader 的类是具体构件,它们实现了 Reader 接口,提供了从文件或输入流中读取字符的基本功能。
  3. 抽象装饰类(Decorator)

    • BufferedReader 类本身可以看作是一个抽象装饰类,它实现了 Reader 接口,并持有一个 Reader 类型的成员变量,这个变量可以是任何实现了 Reader 接口的对象。
  4. 具体装饰类(ConcreteDecorator)

    • 在 BufferedReader 的使用中,通常不需要创建额外的具体装饰类,因为 BufferedReader 已经提供了所需的缓冲功能。但如果需要更特定的功能,可以通过扩展 BufferedReader 来创建新的具体装饰类。

BufferedReader 的工作方式如下:

  • 它接受一个 Reader 对象作为参数,并将其封装在内部。
  • 它提供了一系列方法来读取字符,如 read()readLine()read(char[] cbuf) 等,这些方法利用内部的 Reader 对象来实际读取数据。
  • 它在读取操作中实现了缓冲机制,比如在 read(char[] cbuf) 方法中,它会尝试从内部缓冲区读取字符,如果缓冲区不足,才会从底层的 Reader 对象中读取更多数据,并填充缓冲区。

使用 BufferedReader 的好处包括:

  • 提高效率:通过减少实际的 I/O 操作次数来提高读取性能。
  • 灵活性:可以与任何实现了 Reader 接口的类一起使用,为它们提供缓冲功能。

BufferedReader的装饰器模式使用示例

Reader reader = new FileReader("example.txt");
BufferedReader bufferedReader = new BufferedReader(reader);String line;
while ((line = bufferedReader.readLine()) != null) {System.out.println(line);
}bufferedReader.close();

在这个例子中,FileReader 是具体构件,提供了从文件读取数据的基本功能。BufferedReader 是装饰器,为 FileReader 添加了缓冲功能,提高了读取效率。通过装饰器模式,我们可以在不修改 FileReader 的情况下,动态地为其添加新功能。

相关文章:

【设计模式系列】装饰器模式

目录 一、什么是装饰器模式 二、装饰器模式中的角色 三、装饰器模式的典型应用场景 四、装饰器模式在BufferedReader中的应用 一、什么是装饰器模式 装饰器模式是一种结构型设计模式,用于在不修改对象自身的基础上,通过创建一个或多个装饰类来给对象…...

你真的知道TCP协议中的序列号确认、上层协议及记录标识问题吗?

引言 在前面的内容中,我们已经详细讲解了一系列与TCP相关的面试问题。然而,这些问题都是基于个别知识点进行扩展的。今天,我们将重点讨论一些场景问题,并探讨如何解决这些问题。 序列号确认问题 当A主机与B主机建立了TCP连接后…...

一家生物技术企业终止,科创属性可能不足,报告期内专利数猛增

轩凯生物九成以上营业收入来源于植物营养领域,收入来源结构单一,产品下游应用领域较为集中。报告期内公司应收账款账面价值逐年上升,回款比例显著低于前两年,遭交易所问询是否存在较大的坏账风险。 轩凯生物核心技术是否成熟以及是…...

使用 Python 的 BeautifulSoup(bs4)解析复杂 HTML

使用 Python 的 BeautifulSoup(bs4)解析复杂 HTML:详解与示例 在 Web 开发和数据分析中,解析 HTML 是一个常见的任务,尤其是当你需要从网页中提取数据时。Python 提供了多个库来处理 HTML,其中最受欢迎的就…...

Spring Cache Caffeine 高性能缓存库

​ Caffeine 背景 Caffeine是一个高性能的Java缓存库,它基于Guava Cache进行了增强,提供了更加出色的缓存体验。Caffeine的主要特点包括: 高性能:Caffeine使用了Java 8最新的StampedLock乐观锁技术,极大地提高了缓存…...

Python3入门--数据类型

文章目录 一、基础语法编码标识符注释单行注释以 # 开头多行注释用多个 # 号,还有 和 """ 空行行与缩进同一行显示多条语句多行语句 二、数据类型Number(数字)type和isinstance查询变量类型数值运算 String(字符串…...

开发运维警示录-20241024

开发警示录 1、作为开发,不要私自修改业务人员给的SQL语句,虽然个人感觉SQL很冗余,效率低等。 2、开发前,要明确需求,必要时通过图和文字形成文档与需求方确认、留痕。 3、开发复杂的业务逻辑代码前,先疏通…...

Linux运维_搭建smb服务

Samba(SMB)是一个开源软件,允许Linux和Unix系统与Windows系统共享文件和打印机。以下是一些关于Samba和SMB的基本信息和操作步骤: Samba 和 SMB 基本概念 Samba:实现了SMB(Server Message Block&#xff…...

vue3移动端可同时上传照片和视频的组件

uni-app中的uni-file-picker可单独上传照片或视频,但不支持同时上传照片和视频。本篇博客使用image标签和video标签实现移动端(H5app小程序)中照片和视频的同时上传。 本篇博客采用的是照片和视频的单独上传,但可同时展示&#xf…...

PyQt入门指南二十七 QTableView表格视图组件

# 创建一个QStandardItemModel实例,用于存储表格数据model QStandardItemModel(4, 2) # 4行2列# 填充模型数据for row in range(4):for column in range(2):item QStandardItem(fRow {row}, Column {column})model.setItem(row, column, item)# 创建一个QTableVi…...

AI学习指南深度学习篇-自注意力机制(Self-Attention Mechanism)

AI学习指南深度学习篇—自注意力机制(Self-Attention Mechanism) 在深度学习的研究领域,自注意力机制(Self-Attention Mechanism)作为一种创新的模型结构,已成为了神经网络领域的一个重要组成部分&#xf…...

【JAVA毕业设计】基于Vue和SpringBoot的校园管理系统

本文项目编号 T 026 ,文末自助获取源码 \color{red}{T026,文末自助获取源码} T026,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 管…...

你对MySQL的having关键字了解多少?

在MySQL中,HAVING子句用于在数据分组并计算聚合函数之后,对结果进行进一步的过滤。它通常与GROUP BY子句一起使用,以根据指定的条件过滤分组。HAVING子句的作用类似于WHERE子句,但WHERE子句是在数据被聚合之前进行过滤&#xff0c…...

【STM32编码器】【STM32】

提示:一般情况下我们会设计一个硬件电路模块来自动完成简单重复而高频的计算 文章目录 一、为什么通常情况下不使用外部中断来对编码器的脉冲进行计数?二、编码器速度测量程序设计思路三、正交编码器四、初始化流程五、STM32正交编码器输入捕获模式配置示…...

Python轴承故障诊断 (13)基于故障信号特征提取的超强机器学习识别模型

往期精彩内容: Python-凯斯西储大学(CWRU)轴承数据解读与分类处理 Pytorch-LSTM轴承故障一维信号分类(一)-CSDN博客 Pytorch-CNN轴承故障一维信号分类(二)-CSDN博客 Pytorch-Transformer轴承故障一维信号分类(三)-CSDN博客 三十多个开源…...

VScode分文件编写C++报错 | 如何进行VScode分文件编写C++ | 不懂也能轻松解决版

分文件编写遇到的问题 分文件编写例子如下所示: 但是直接使用 Run Code 或者 调试C/C文件 会报错如下: 正在执行任务: C/C: g.exe 生成活动文件 正在启动生成… cmd /c chcp 65001>nul && D:\Librarys\mingw64\bin\g.exe -fdiagnostics-col…...

洞察前沿趋势!2024深圳国际金融科技大赛——西丽湖金融科技大学生挑战赛技术公开课指南

在当前信息技术与“互联网”深度融合的背景下,金融行业的转型升级是热门话题,创新与发展成为金融科技主旋律。随着区块链技术、人工智能技术、5G通信技术、大数据技术等前沿科技的飞速发展,它们与金融领域的深度融合,正引领着新型…...

Unity3D学习FPS游戏(4)重力模拟和角色跳跃

前言:前面两篇文章,已经实现了角色的移动和视角转动,但是角色并没有办法跳跃,有时候还会随着视角移动跑到天上。这是因为缺少重力系统,本篇将实现重力和角色跳跃功能。觉得有帮助的话可以点赞收藏支持一下!…...

C#基础知识-枚举

目录 枚举 1.分类 1.1普通枚举 1)默认情况 2)指定起始值 1.2标志枚举(Flag Enum) 位运算符与标志枚举 1)组合标志 2)检查标志 2.枚举与不同类型之间的转换 1)枚举->整型 2&#…...

系统架构设计师教程 第2章 2.1-2计算机系统及硬件 笔记

2.1计算机系统概述 ★☆☆☆☆ 计算机系统 (Computer System) 是指用于数据管理的计算机硬件、软件及网络组成的系统。 一般指由硬件子系统和软件子系统组成的系统,简称为计算机。 将连接多个计算机以实现计算机间数据交换能力的网络设备,称为计算机网…...

vscode里如何用git

打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...