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

文章目录

  • 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可以自动配置各种组件,如数据源、事务管理器等,这些自动配置的组件可以被用户的自定义配置所增强或覆盖。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/22949.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端面试题日常练-day53 【面试题】

题目 希望这些选择题能够帮助您进行前端面试的准备,答案在文末 1. 在PHP中,以下哪个函数可以用于从一个数组的末尾删除一个元素并返回被删除的元素? a) array_pop() b) array_push() c) array_shift() d) array_unshift() 2. 在PHP中&…

列存在 OceanBase 数据库架构中的应用与演进

OceanBase 4.3 版本上线了列存功能,以满足实时分析的需求。 本文作为《特性解读:列存技术》的后续,将详细阐述列存技术在OceanBase数据库架构中的应用、发展历程,以及未来的趋势。 一、前言 1970 年,关系模型之父 Co…

LeakSearch:针对网络公开凭证的安全扫描与检测工具

关于LeakSearch 在红队演戏过程中,往往需要获取到针对目标域的访问权限。在这个过程中,很多红队人员会选择使用暴露在互联网上的代理服务器来实现目标域的访问,那么此时就需要在互联网上收集公开暴露的凭证信息。 对于蓝队来说,…

Playwright+Python+Pytest:基础方法二次封装简化及链式调用

引言 随着Web应用的日益复杂化,自动化测试成为了确保软件质量的关键环节。Playwright 是一个强大的自动化库,它支持在 Chromium、Firefox 和 WebKit 中运行自动化脚本。本文将介绍如何使用 Playwright 的 Python 同步 API 来简化点击和填充操作&#xf…

阿里云邮件推送配置教程:API配置的步骤?

阿里云邮件推送服务如何使用?如何配置邮件推送服务? 阿里云提供了强大的邮件推送服务,帮助企业高效地发送邮件通知、验证码、营销活动等。Aok将详细介绍阿里云邮件推送的配置教程,以及API配置的步骤,同时简要提及AokS…

数据流图要点和难点实际应用

数据流图(Data Flow Diagram,DFD)是一种图形化表示信息系统中数据流动和处理的方式。它主要用于描述系统如何接收输入数据,经过一系列的处理步骤,然后产生输出数据。数据流图在系统设计阶段特别有用,因为它可以帮助开发人员、业务分析师和其他利益相关者更好地理解系统的…

Python字符串数据类型之字符串

四、Python数据类型 4.1、Python内置数据类型 整型:int浮点型:float布尔类型:bool字符串:str二进制类型:bytes、bytearray复数:complex列表:list元组:tuple字典:dict a…

C#WPF控件Textbox绑定浮点型数据限制小数位方法

本文讲解C#WPF控件Textbox绑定浮点型数据限制小数位方法。 XAML中,使用StringFormat来格式化TextBox的文本 <Window x:Class="WpfApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.m…

【使用 uiautomator2 脚本进行波点音乐app自动化操作的教程】

本教程将指导您使用 uiautomator2 库编写脚本&#xff0c;实现自动化操作。如果您需要在设备断开连接或出现异常时重新连接设备并继续执行任务&#xff0c;这里有一份详细的代码示例和使用说明。 环境准备 安装 Python&#xff1a; 确保您的系统上安装了 Python&#xff08;推…

[数据集][目标检测]盲道检测数据集VOC+YOLO格式2173张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2173 标注数量(xml文件个数)&#xff1a;2173 标注数量(txt文件个数)&#xff1a;2173 标注…

基于R语言BIOMOD2 及机器学习方法的物种分布模拟与案例分析实践技术

BIOMOD2是一个R软件包&#xff0c;用于构建和评估物种分布模型&#xff08;SDMs&#xff09;。它集成了多种统计和机器学习方法&#xff0c;如GLM、GAM、SVM等&#xff0c;允许用户预测和分析物种在不同环境条件下的地理分布。通过这种方式&#xff0c;BIOMOD帮助研究者评估气候…

常用接口测试及接口抓包常用的测试工具

一、常用抓包工具 01、F12 Web端的话&#xff0c;google浏览器直接F12开发者模式 点击network进行抓包分析。 02、Fiddler抓包工具 客户端和服务端的http代理&#xff0c;客户端所有的请求都要先经过Fiddler&#xff0c;到响应的服务端&#xff0c;然后端返回的所有数据也都…

pytorch数学操作

文章目录 1.torch.bitwise_not()2.torch.bitwise_and()3.torch.ceil()3.torch.clamp()4.torch.torch.floor() 1.torch.bitwise_not() 在 PyTorch 中&#xff0c;torch.bitwise_not() 是一个函数&#xff0c;用于执行逐元素的位非&#xff08;bitwise NOT&#xff09;操作。 t…

如何组织基于Sqlalchemy的项目

在使用 SQLAlchemy 构建项目时&#xff0c;可以遵循一些常用的组织结构和最佳实践&#xff0c;以确保项目清晰、易于维护。下面就是我在构建项目时遇到的一些问题&#xff0c;并做了详细的记录&#xff0c;为了方便大家学习少走一些弯路。 1、问题背景 在基于Sqlalchemy的项目…

IDEA的使用配置Maven(及selenium+webdriver的下载配置)

一. 下载maven 1. maven官网下载链接 2.​​安装第二行第一列的zip压缩包 ​​​​​​​​ 二. 配置环境变量 1.新建环境变量 2.在系统变量Path环境变量中添加%Maven_HOME%\bin 三.验证环境变量是否配置成功 winr >cmd>mvn -v 如果出现Maven的版本信息&#xff0…

Matlab解决矩阵微分方程建模(代码开源)

#用matlab解决施密特正交规范化矩阵之后&#xff0c;我又想到矩阵的微分方程计算量真的太大了&#xff0c;来回转化让我头大&#xff0c;于是我尝试了一下用matlab建立模型来解决这类问题。 代码部分如下&#xff1a;注解还挺清晰的&#xff1a; %%%解微分方程组%eg&#xff…

【设计模式】代理模式(结构型)⭐⭐⭐

文章目录 1.概念1.1 什么是代理模式1.2 优点与缺点 2.实现方式2.1 静态代理2.2 动态代理 3. Java 哪些地方用到了代理模式4. Spring 哪些地方用到了代理模式 1.概念 1.1 什么是代理模式 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许…

带你认识ffmpeg

FFmpeg是一个开源的跨平台音视频处理工具集&#xff0c;它提供了丰富的音视频处理功能和库&#xff0c;被广泛应用于音视频编解码、格式转换、流媒体处理等领域。 应用场景&#xff1a; 视频编解码&#xff1a;FFmpeg可以对各种视频格式进行编解码&#xff0c;包括但不限于AV…

类的特殊成员函数

使用类的嵌套&#xff0c;并自定义析构函数 #include <iostream>using namespace std; class Per{ private:string name;int age;double hight;double weight; public:Per(string name,int age,double hight,double weight):name(name),age(age),hight(hight),weight(we…

图片如何修改尺寸?四种好用的修改图片尺寸方法!

图片如何修改尺寸&#xff1f;图片是一种常见的文件类型&#xff0c;它存在于什么生活的方方面面&#xff0c;虽然图片很好用&#xff0c;但是大家日常也要注意图片的尺寸&#xff0c;如果图片尺寸不对是会带来很多问题的&#xff0c;下面小编就举例说明几个问题&#xff0c;首…