java设计模式:03-04-装饰器模式
装饰器模式(Decorator Pattern)
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰器模式通过创建一个装饰类来包装原有的类,并在保留原有类的接口的情况下,提供额外的功能。
装饰器模式的应用场景
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责:如给一个图形对象添加边框、颜色等属性。
- 当不能采用生成子类的方法进行扩展时:如有大量独立的扩展,或扩展是动态的。
装饰器模式的实现方式
1. 传统实现方式
思想:通过定义一个抽象的组件类,所有的具体组件和装饰类都继承自该组件类。装饰类包含一个组件对象,并在调用其方法前后进行增强。
实现方式:
// 抽象组件
abstract class Component {public abstract void operation();
}// 具体组件
class ConcreteComponent extends Component {public void operation() {System.out.println("ConcreteComponent operation");}
}// 抽象装饰类
abstract class Decorator extends Component {protected Component component;public Decorator(Component component) {this.component = component;}public void operation() {component.operation();}
}// 具体装饰类A
class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}public void operation() {super.operation();addedBehavior();}public void addedBehavior() {System.out.println("ConcreteDecoratorA added behavior");}
}// 具体装饰类B
class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}public void operation() {super.operation();addedBehavior();}public void addedBehavior() {System.out.println("ConcreteDecoratorB added behavior");}
}// 客户端代码
public class DecoratorPattern {public static void main(String[] args) {Component component = new ConcreteComponent();Component decoratorA = new ConcreteDecoratorA(component);Component decoratorB = new ConcreteDecoratorB(decoratorA);decoratorB.operation();}
}
优点:
- 可以动态地添加和删除对象的职责,比静态继承更加灵活。
- 通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。
- 符合开闭原则,可以在不修改原有代码的情况下扩展对象的新功能。
缺点:
- 会产生许多小对象,增加了系统的复杂性。
- 多层装饰时会增加调试的难度,特别是出现问题时难以找到问题所在。
2. 使用接口实现装饰器模式
思想:通过定义一个接口,所有的具体组件和装饰类都实现该接口,装饰类包含一个接口类型的对象,并在调用其方法前后进行增强。
实现方式:
// 抽象组件接口
interface Component {void operation();
}// 具体组件
class ConcreteComponent implements Component {public void operation() {System.out.println("ConcreteComponent operation");}
}// 抽象装饰类
abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}public void operation() {component.operation();}
}// 具体装饰类A
class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}public void operation() {super.operation();addedBehavior();}public void addedBehavior() {System.out.println("ConcreteDecoratorA added behavior");}
}// 具体装饰类B
class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}public void operation() {super.operation();addedBehavior();}public void addedBehavior() {System.out.println("ConcreteDecoratorB added behavior");}
}// 客户端代码
public class InterfaceDecoratorPattern {public static void main(String[] args) {Component component = new ConcreteComponent();Component decoratorA = new ConcreteDecoratorA(component);Component decoratorB = new ConcreteDecoratorB(decoratorA);decoratorB.operation();}
}
优点:
- 接口使得装饰类和具体组件更加解耦,符合依赖倒置原则。
- 接口可以更容易地进行单元测试和模拟对象。
缺点:
- 同样会产生许多小对象,增加系统复杂性。
- 多层装饰时仍然会增加调试的难度。
总结
| 实现方式 | 优点 | 缺点 | 
|---|---|---|
| 传统实现方式 | 动态添加和删除职责,符合开闭原则,行为组合多样化 | 产生许多小对象,系统复杂性增加,多层装饰调试难度大 | 
| 使用接口实现装饰器模式 | 解耦装饰类和具体组件,符合依赖倒置原则,易于单元测试和模拟对象 | 产生许多小对象,系统复杂性增加,多层装饰调试难度大 | 
选择哪种实现方式应根据具体的需求和系统的复杂度来决定。如果希望组件和装饰类之间更加解耦且易于测试,可以选择使用接口实现装饰器模式。如果更关注具体类的扩展性和灵活性,可以选择传统的实现方式。
相关文章:
java设计模式:03-04-装饰器模式
装饰器模式(Decorator Pattern) 装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰器模式通过创建一个装饰类来包装原有的类,…...
 
通过splunk web服务将服务器上文件下载到本地
1. 需求说明 工作中经常遇到需要将服务器上的文件下载到本地,但是由于各种网络环境限制,没办法使用winscp或者xftp工具,那么如何将服务器上的文件下载下来呢? 这里提供一种思路: 如果服务器上安装有web服务,可将待下…...
Node.js 路由
Node.js 路由 介绍 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它允许开发者使用 JavaScript 编写服务器端代码。Node.js 的一个核心特性是其事件驱动和非阻塞 I/O 模型,这使得它非常适合处理高并发和 I/O 密集型的应用程序。在 Node.js 中,路由是指确定应…...
 
Adobe国际认证详解-网页设计认证专家行业应用场景解析
在当今数字化时代,网页设计已成为各行各业不可或缺的一环。而网页设计认证专家,作为经过Adobe国际认证体系严格考核的专业人才,正逐渐成为行业内炙手可热的存在。他们凭借深厚的网页设计理论基础和实践经验,为各行各业提供了高质量…...
ESC(ELectronic Stability Control,电子稳定控制系统)
ESC通过实时监测车辆的动态参数,以及车辆轮胎的实际运动状态,通过调节车辆制动系统和发动机输出力,使车辆在紧急或危险情况下保持稳定,防止侧滑和失控。 ESC组成部分 传感器:用于检测车辆的动态参数,如车…...
 
减分兔搜题-12123学法减分20题目及答案 #媒体#职场发展
对于即将参加驾驶考试的朋友来说,掌握一些经典题目和答案至关重要。今天,我就为大家带来了这样一份干货——20道驾驶考试题目和答案,助你轻松应对考试!这些题目不仅包括了考试中常考的内容,还有针对难点和重点的详细解…...
 
java用freemarker导出word
freemarker导出word 第一步、将word转换为xml格式第二步、将转换后的xml文件修改后缀为ftl后复制到项目 resources 目录下(可以自己新建一个文件夹放在文件夹中)第三步、格式化xml代码(如果问价太大可能会无法格式化)这时候需要在…...
 
CH01_WPF概述
第1章:WPF概述 本章目标 了解Windows图形演化了解WPF高级API了解分辨率无关性概念了解WPF体系结构了解WPF 4.5 WPF概述  欢迎使用 Windows Presentation Foundation (WPF) 桌面指南,这是一个与分辨率无关的 UI 框架,使用基于矢量的呈现引…...
 
秒懂设计模式--学习笔记(11)【结构型-享元模式】
目录 10、享元模式10.1 享元模式10.2 举例10.2.1 马赛克10.2.2 游戏地图(以草原地图作为范例) 10.3 总结 10、享元模式 10.1 享元模式 “享元”则是共享元件的意思享元模式的英文flyweight是轻量级的意思,这就意味着享元模式能使程序变得更…...
Python爬虫——1爬虫基础(一步一步慢慢来)
一、爬虫是什么? (spider) Python 爬虫是利用编程语言 Python 来获取互联网上的数据的技术。它可以自动化地访问网页、提取信息并进行数据处理。以下是Python爬虫的基础知识和步骤: 主要特点和功能: 自动化浏览&#…...
【js自学打卡9】抛出异常 / 幂计算 / 发布订阅 / map小知识点
1. 抛出异常的写法 抛出一个简单的字符串错误 throw Error2; // 抛出一个字符串抛出一个Error对象 throw new Error(出错了!);抛出一个自定义错误对象 function UserError(message) {this.message message;this.name "UserError"; } throw new User…...
ArcGIS Pro SDK (九)几何 7 多点
ArcGIS Pro SDK (九)几何 7 多点 文章目录 ArcGIS Pro SDK (九)几何 7 多点1 构造多点 - 从映射点的枚举2 构造多点 - 使用 MultipointBuilderEx3 修改多点的点4 从多点检索点、2D 坐标、3D 坐标 环境:Visual Studio 2…...
服务器注意事项
1. 远程服务器不允许关机,只能重启; 2. 重启服务器应关闭服务; 3. 不要在服务器访问高峰运行高负载命令; 4. 远程配置防火墙是不要把自己踢出服务器; 5. 制定合理的密码规范并定期更新; 6. 合理分配权…...
 
学生信息管理系统设计
学生信息管理系统的设计是一个综合性的项目,涉及到数据的存储、检索、更新和删除等基本操作,同时也需要考虑系统的易用性、安全性和扩展性。以下是一些关键步骤和要素,用于指导设计这样一个系统: 1. 需求分析 目标用户ÿ…...
 
Python求均值,方差,标准差
参考链接:变异系数(Coefficient of Variation,COV)和协方差(Covariance, Cov)-CSDN博客 参考链接:pandas中std和numpy的np.std区别_numpy pandas std-CSDN博客 在计算蛋白质谱数据中的每个蛋白对应的变异…...
 
DDei在线设计器-HTML渲染
Html渲染 HtmlViewer插件通过将一个外部DIV附着在图形控件上,从而改变原有图形的显示方式。允许使用者自己定义HTML通过HTML元素。本示例演示了通过Html来扩展渲染图形,从而获得更加丰富的图形展现。 通常情况下,我们创建的图形控件ÿ…...
【React Hooks原理 - useSyncExternalStore】
概述 在React项目中说到状态管理,我们第一时间想到的就是使用useState、useReducer这种Hooks来进行状态管理。但是这种是针对React内部的状态,如果有时候我们需要订阅外部的状态并影响React组件的更新的话,那通过这种内部状态管理API显然不能…...
 
C++STL初阶(7):list的运用与初步了解
在了解了vector之后,我们只需要简单学习List与vector不一样的接口即可 1.list的基本接口 1.1 iterator list中,与vector最大的区别就是迭代器由随机迭代器变成双向迭代器 string和vector中的迭代器都是随机迭代器,支持-等,而LIS…...
 
el-menu弹出菜单样式不生效
1. 使用 ruoyi 项目时出现的问题。 <template><el-menu:default-active"activeMenu":collapse"false":unique-opened"true"class"container":collapse-transition"true"mode"horizontal"><sideba…...
Springboot 3.x - Reactive programming (2)
三、WebFlux Blocking Web vs. Reactive Web Blocking Web (Servlet) and Reactive Web (WebFlux) have significant differences in several aspects. 1. Front Controller Servlet-Blocking Web: Uses DispatcherServlet as the front controller to handle all HTTP req…...
 
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
 
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
 
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
 
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
 
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
 
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
 
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
 
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
