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

【设计模式】装饰器模式(结构型)⭐⭐

文章目录

  • 1.概念
    • 1.1 什么是装饰器模式
    • 1.2 优点与缺点
  • 2.实现方式
  • 3. Java 哪些地方用到了装饰器模式
  • 4. Spring 哪些地方用到了装饰器模式

1.概念

1.1 什么是装饰器模式

它允许用户在不修改现有对象的代码的情况下向对象添加新的功能;这种模式是通过创建一个包含该对象的包装对象来实现的,从而扩展该对象的功能。

1.2 优点与缺点

优点:
1.灵活性和扩展性:装饰器模式允许在运行时向对象添加新的行为,提供了比继承更大的灵活性。
2.遵守开闭原则:装饰器模式允许向系统添加新的行为而不需要修改现有代码,这符合开闭原则(软件实体应该对扩展开放,对修改关闭)。
3.代码复用:装饰器可以被多个对象共享,这减少了代码的重复,提高了代码复用性。
4.对象功能增强:在不改变原有对象的情况下,可以有选择性地增强对象的功能。
5.组合优于继承:装饰器模式使用对象组合而不是继承来扩展功能,这有助于避免继承层次可能带来的复杂性和脆弱性。
缺点:
1.增加复杂性:装饰器模式可能会增加系统的复杂性,因为需要创建多个小对象来表示不同的功能。2.调试困难:由于装饰器可以嵌套使用,调试和理解运行时的行为可能会变得更加困难。
3.性能问题:装饰器模式可能会引入额外的性能开销,因为需要创建额外的对象,并且可能需要通过多个装饰器来解析方法调用。
4.设计复杂:如果使用不当,装饰器模式可能会导致设计变得复杂,特别是当装饰器之间的关系变得复杂时。
5.接口限制:装饰器模式要求装饰器和被装饰的对象实现相同的接口,这在某些情况下可能是不切实际的。

2.实现方式

①定义接口

public interface Beverage {String getDescription();double cost();
}

②创建一个实现了Beverage接口的具体类SimpleCoffee

public class SimpleCoffee implements Beverage {@Overridepublic String getDescription() {return "Simple Coffee";}@Overridepublic double cost() {return 1.0;}
}

③定义一个装饰器类CondimentDecorator,它也实现了Beverage接口,并持有一个Beverage对象的引用:

public abstract class CondimentDecorator implements Beverage {protected Beverage beverage;public CondimentDecorator(Beverage beverage) {this.beverage = beverage;}public abstract String getDescription();
}

④创建具体的装饰器类,比如Milk、Sugar和Chocolate,它们都扩展了CondimentDecorator并添加了各自的成本和描述:

public class Milk extends CondimentDecorator {public Milk(Beverage beverage) {super(beverage);}@Overridepublic String getDescription() {return beverage.getDescription() + ", Milk";}@Overridepublic double cost() {return beverage.cost() + 0.5;}
}public class Sugar extends CondimentDecorator {public Sugar(Beverage beverage) {super(beverage);}@Overridepublic String getDescription() {return beverage.getDescription() + ", Sugar";}@Overridepublic double cost() {return beverage.cost() + 0.1;}
}public class Chocolate extends CondimentDecorator {public Chocolate(Beverage beverage) {super(beverage);}@Overridepublic String getDescription() {return beverage.getDescription() + ", Chocolate";}@Overridepublic double cost() {return beverage.cost() + 0.3;}
}

⑤ 使用

public class DecoratorDemo {public static void main(String[] args) {Beverage coffee = new SimpleCoffee();System.out.println(coffee.getDescription() + " $" + coffee.cost());coffee = new Milk(coffee);coffee = new Sugar(coffee);coffee = new Chocolate(coffee);System.out.println(coffee.getDescription() + " $" + coffee.cost());}
}

3. Java 哪些地方用到了装饰器模式

Java I/O 流
Java的I/O库广泛使用了装饰器模式来增强基本输入输出流的功能。例如,BufferedInputStream和BufferedOutputStream类通过装饰基本的InputStream和OutputStream来提供缓冲功能。同样,DataInputStream和DataOutputStream为基本的流添加了读写基本数据类型的能力。
Java Servlet API
Java Servlet API中的HttpServletRequestWrapper和HttpServletResponseWrapper类允许开发者通过装饰原始的HttpServletRequest和HttpServletResponse对象来添加或修改功能。
Java动态代理
Java的动态代理机制允许在运行时创建一个实现了一组接口的代理类实例。这个代理实例实际上是一个装饰器,它可以在不修改原始对象代码的情况下,为原始对象添加新的行为,如事务管理、日志记录等。
Spring框架
Spring框架在很多地方使用了装饰器模式,例如在AOP(面向切面编程)中,Spring会创建代理对象来包装目标对象,以实现事务管理、权限检查等横切关注点的功能。
Apache Commons IO
Apache Commons IO库提供了一些装饰器类,如ProxyInputStream和ProxyOutputStream,这些类可以用来创建自定义的流装饰器。
JDBC
JDBC驱动程序有时会使用装饰器模式来增强或修改原始的Connection、Statement或ResultSet对象的行为。
JAX-RS
JAX-RS(Java API for RESTful Web Services)中的客户端API允许使用装饰器模式来增强或修改Client、WebTarget、Invocation等对象的行为。

4. Spring 哪些地方用到了装饰器模式

AOP(面向切面编程):
Spring AOP允许通过声明式方式添加横切关注点(如日志记录、事务管理、安全检查等)到目标对象。Spring创建代理对象来包装目标对象,这些代理对象在调用目标方法前后执行额外的代码。这实际上是一种装饰器模式的应用,它允许在不修改目标对象代码的情况下增强其行为。
事务管理
在Spring中,事务管理通常是通过AOP实现的。Spring可以为目标方法创建一个代理,该代理在方法执行前后管理事务的开启和关闭,而无需修改目标方法的代码。
Spring Security
Spring Security使用方法拦截器来实现安全控制。它可以为目标方法创建代理,这些代理在方法执行前检查用户的权限,如果用户没有足够的权限,则不允许执行目标方法。
Spring Data JPA
Spring Data JPA中的仓库(Repository)可以通过自定义的实现来扩展。开发者可以创建一个自定义的仓库实现,并通过Spring的配置将其与标准仓库接口关联起来。这实际上是在使用装饰器模式来扩展仓库的功能。
Spring WebFlux
Spring WebFlux中的WebFilter和WebExceptionHandler可以被视为装饰器模式的应用。它们允许在请求处理的各个阶段添加额外的处理逻辑,而不需要修改原始的处理器代码。
Spring Cloud
在Spring Cloud中,装饰器模式被用于实现服务断路器、负载均衡等功能。例如,Hystrix断路器可以通过装饰原始的服务调用逻辑来添加断路器功能,从而在服务调用失败时提供备选方案。
Spring Boot
Spring Boot自动配置的原理也可以看作是装饰器模式的一种应用。Spring Boot可以自动配置各种组件,如数据源、事务管理器等,这些自动配置的组件可以被用户的自定义配置所增强或覆盖。

相关文章:

【设计模式】装饰器模式(结构型)⭐⭐

文章目录 1.概念1.1 什么是装饰器模式1.2 优点与缺点 2.实现方式3. Java 哪些地方用到了装饰器模式4. Spring 哪些地方用到了装饰器模式 1.概念 1.1 什么是装饰器模式 它允许用户在不修改现有对象的代码的情况下向对象添加新的功能;这种模式是通过创建一个包含该对…...

计算机网络--应用层

计算机网络–计算机网络概念 计算机网络–物理层 计算机网络–数据链路层 计算机网络–网络层 计算机网络–传输层 计算机网络–应用层 1. 概述 因为不同的网络应用之间需要有一个确定的通信规则。 1.1 两种常用的网络应用模型 1.1.1 客户/服务器模型(Client/Se…...

计算机网络 —— 网络层(IP数据报)

计算机网络 —— 网络层(IP数据报) 网络层要满足的功能IP数据报IP数据报格式IP数据报首部格式数据部分 IP数据报分片 我们今天进入网络层的学习。 网络层要满足的功能 网络层作为OSI模型中的第三层,是计算机网络体系结构的关键组成部分&…...

Clo3D导出服装动画,使用Unity3D展示

1.前言 Clo3D是一款应用于时装行业的3D服装设计软件,其强大的布料模拟算法可在3D空间中实现设计、制版、试衣和走秀,大幅提升数字作品逼真度和制作效率。为了让服装动画效果展示在Unity3D上模拟效果,需要Clo3D模拟出逼着的衣服动画。总体流程为Clo3D - Mixamo -Blen…...

LSTM 词语模型上的动态量化

原文链接 (beta) Dynamic Quantization on an LSTM Word Language Model — PyTorch Tutorials 2.3.0cu121 documentation 引言 量化涉及将模型的权重和激活值从浮点数转换为整数,这样可以缩小模型大小,加快推理速度,但对准确性的影响很小…...

STM32 proteus + STM32Cubemx仿真教程(第一课LED教程)

文章目录 前言一、STM32点亮LED灯的原理1.1GPIO是什么1.2点亮LED灯的原理 二、STM32Cubemx创建工程三、proteus仿真电路图四、程序代码编写1.LED灯操作函数介绍HAL_GPIO_WritePin函数原型参数说明示例代码 HAL_GPIO_TogglePin函数原型参数说明示例代码 2.代码编写3.烧写程序 总…...

享元模式

前言 享元模式:运用共享技术有效地支持大量细粒度的对象。 在享元对象内部并且不会随环境改变而改变的共享部分,可以称为是享元对象的内部状态,而随环境改变而改变的、不可以共享的状态就是外部状态了。事实上,享元模式可以避免大…...

R语言数据分析16-针对芬兰污染指数的分析与考察

1. 研究背景及意义 近年来,随着我国科技和经济高速发展,人们生活质量也随之显著提高。但是, 环境污染问题也日趋严重,给人们的生活质量和社会生产的各个方面都造成了许多不 利的影响。空气污染作为环境污染主要方面,更…...

Search用法Python:深入探索搜索功能的应用与技巧

Search用法Python:深入探索搜索功能的应用与技巧 在Python编程中,搜索功能是一项至关重要的技能,它能够帮助我们快速定位并处理数据。然而,对于初学者来说,如何高效地使用搜索功能可能会带来一些困惑。本文将从四个方…...

STM32的FreeRtos的学习

首先就是去官网下载一个源文件:FreeRtos官网 下载下来的是一个zip文件,解压缩了。 然后再工程文件夹中创建个文件夹: 在这个文件夹中创建3个文件夹: 然后开始把下载下来的文件夹中的文件挑选出来放到我们的工程文件夹中&#xff1…...

从零入手人工智能(2)——搭建开发环境

1.前言 作为一名单片机工程师,想要转型到人工智能开发领域的道路确实充满了挑战与未知。记得当我刚开始这段旅程时,心中充满了迷茫和困惑。面对全新的领域,我既不清楚如何入手,也不知道能用人工智能干什么。正是这些迷茫和困惑&a…...

Web前端指南

前言 前端开发员主要负责网站的设计、外观和感觉。他们设计引人入胜的在线用户体验,激发用户兴趣,鼓励用户重复访问。他们与设计师密切合作,使网站美观、实用、快捷。 如果您喜欢创造性思维、打造更好的体验并对视觉设计感兴趣,这将是您的理想职业道路。 探讨前端、后端以…...

AI菜鸟向前飞 — LangChain系列之十七 - 剖析AgentExecutor

AgentExecutor 顾名思义,Agent执行器,本篇先简单看看LangChain是如何实现的。 先回顾 AI菜鸟向前飞 — LangChain系列之十四 - Agent系列:从现象看机制(上篇) AI菜鸟向前飞 — LangChain系列之十五 - Agent系列&#…...

nodejs 第三方库 exiftool-vendored

exiftool-vendored 是一款可以帮助你快捷修改图片信息的第三方库。如果你想要批量修改图片信息的话,那么它是一个不错的选择。 1.导入第三方库 在控制台中执行下面代码即可。 npm install exiftool-vendored --save2.获取信息 这里给出例子。 const { exiftool …...

docker部署redis实践

1.拉取redis镜像 # 拉取镜像 sudo docker pull redis2.创建映射持久化目录 # 创建目录 sudo mkdir -p $PWD/redis/{conf,data}3. 运行redis 容器,查看当前redis 版本号 # 运行 sudo docker run --name redis -d -p 6379:6379 redis # 查看版本号 sudo docker ex…...

Web前端学习之路:深入探索学习时长与技能进阶的奥秘

Web前端学习之路:深入探索学习时长与技能进阶的奥秘 在数字化时代,Web前端技术成为了连接用户与互联网世界的桥梁。对于初学者来说,学习Web前端究竟需要多久,以及如何高效掌握相关技能,一直是困扰他们的难题。本文将从…...

如何不用命令创建用户

都有哪些操作: 1、在/etc/passwd添加一行 2、在/etc/shadow添加一行 3、在/etc/group添加一行 4、创建用户家目录 5、创建用户邮件文件 例如: 创建用户jerry 要求: uid:777 主组:hadoop(800&#xff09…...

基于Python实现可视化分析中国500强排行榜数据的设计与实现

基于Python实现可视化分析中国500强排行榜数据的设计与实现 “Design and Implementation of Visual Analysis for China’s Top 500 Companies Ranking Data using Python” 完整下载链接:基于Python实现可视化分析中国500强排行榜数据的设计与实现 文章目录 基于Python实现…...

VUE3 学习笔记(13):VUE3 下的Element-Plus基本使用

UI是页面的门面,一个好的UI自然令人赏心悦目;国人团队开发的ElementUI在众多UI中较为常见,因此通过介绍它的使用让大家更好的了解第三方UI的使用。 安装 Npm install element-plus --save 或 Cnpm install element-plus --save 配置 全局配置…...

MySql数据库安全加固

设置密码复杂度策略 查看密码策略 SHOW VARIABLES LIKE validate_password%; 设置密码策略 INSTALL PLUGIN validate_password SONAME validate_password.so; 设置登陆失败策略 安装插件(谨慎操作,可能会导致数据库卡死) install plug…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

云计算——弹性云计算器(ECS)

弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...