装饰大师——装饰模式(Java实现)

引言

大家好,上期我们介绍了装饰模式在Python中的实现,今天,我们将继续探讨装饰模式,并展示如何在Java中实现它。

装饰模式概述

装饰模式的核心思想是将功能附加到对象上,而不是通过继承来实现,这种模式包含以下几个关键组成部分:

  1. 组件接口:定义基本功能;
  2. 具体组件:实现基本功能的类;
  3. 装饰器基类:实现组件接口,并包含一个指向组件对象的引用;
  4. 具体装饰器:扩展装饰器基类,实现额外的功能。

装饰模式与其他设计模式(如代理模式、适配器模式)不同之处在于,装饰模式注重动态地为对象添加职责,而不改变对象的接口。

模式结构

类图

示意图

装饰模式的Java实现

在Java中,装饰模式通常通过继承和组合来实现。以下是几种常见的实现方式:

基本实现

以下是一个简单的装饰器例子,它为组件添加打印日志的功能:

// 组件接口
interface Component {void operation();
}// 具体组件
class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("Executing operation in ConcreteComponent");}
}// 装饰器基类
abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {component.operation();}
}// 具体装饰器
class LoggingDecorator extends Decorator {public LoggingDecorator(Component component) {super(component);}@Overridepublic void operation() {System.out.println("Logging before operation");super.operation();System.out.println("Logging after operation");}
}// 测试
public class DecoratorPatternExample {public static void main(String[] args) {Component component = new ConcreteComponent();Component decoratedComponent = new LoggingDecorator(component);decoratedComponent.operation();}
}
多层装饰器的使用

装饰器可以叠加使用,实现多层装饰:

class UppercaseDecorator extends Decorator {public UppercaseDecorator(Component component) {super(component);}@Overridepublic void operation() {System.out.println("Converting to uppercase");super.operation();System.out.println("Converted to uppercase");}
}public class MultiDecoratorExample {public static void main(String[] args) {Component component = new ConcreteComponent();Component decoratedComponent = new LoggingDecorator(new UppercaseDecorator(component));decoratedComponent.operation();}
}

实际应用案例

装饰模式在实际项目中有很多应用场景,例如日志记录、权限验证和性能监控等。

日志记录功能的装饰

通过装饰器为组件添加日志记录功能,可以避免在每个组件中重复写日志代码:

class LoggingDecorator extends Decorator {public LoggingDecorator(Component component) {super(component);}@Overridepublic void operation() {System.out.println("Logging before operation");super.operation();System.out.println("Logging after operation");}
}public class LoggingExample {public static void main(String[] args) {Component component = new ConcreteComponent();Component loggingComponent = new LoggingDecorator(component);loggingComponent.operation();}
}
权限验证功能的装饰

通过装饰器为组件添加权限验证功能,可以在调用实际业务逻辑之前进行权限检查:

class PermissionDecorator extends Decorator {public PermissionDecorator(Component component) {super(component);}@Overridepublic void operation() {if (hasPermission()) {super.operation();} else {System.out.println("Access denied");}}private boolean hasPermission() {// 模拟权限验证逻辑return true; // 可以根据实际情况修改}
}public class PermissionExample {public static void main(String[] args) {Component component = new ConcreteComponent();Component permissionComponent = new PermissionDecorator(component);permissionComponent.operation();}
}
性能监控功能的装饰

通过装饰器为组件添加性能监控功能,可以方便地记录组件的执行时间:

class TimingDecorator extends Decorator {public TimingDecorator(Component component) {super(component);}@Overridepublic void operation() {long startTime = System.currentTimeMillis();super.operation();long endTime = System.currentTimeMillis();System.out.println("Operation took " + (endTime - startTime) + " milliseconds");}
}public class TimingExample {public static void main(String[] args) {Component component = new ConcreteComponent();Component timingComponent = new TimingDecorator(component);timingComponent.operation();}
}

装饰模式的优缺点

优点
  1. 单一职责原则:可以将职责划分到不同的类中,使每个类的功能更加单一和明确;
  2. 动态扩展功能:可以在运行时添加或删除功能,而无需修改原有代码;
  3. 灵活性高:通过不同的装饰器组合,可以实现多种不同的功能扩展;
  4. 减少代码重复:可以避免在多个类中重复实现相同的功能,减少代码冗余。
缺点
  1. 增加复杂性:装饰器的嵌套使用可能会导致代码结构复杂,不易理解和维护;
  2. 调试困难:由于装饰器改变了函数的行为,调试时可能不容易追踪到问题的根源;
  3. 性能开销:多层装饰器可能会增加函数调用的开销,影响性能。

应用场景

装饰模式适用于以下场景:

  1. 需要动态添加功能:例如为已有功能添加日志记录、性能监控或权限验证等;
  2. 功能扩展频繁:例如在项目中需要经常为不同对象添加或移除功能;
  3. 不希望修改原有代码:例如在使用第三方库时,不希望直接修改其源代码,而是通过装饰器来扩展其功能;
  4. 跨切面关注点:例如在面向切面编程中,装饰模式可以用于处理日志、事务管理、异常处理等横切关注点。

总结

通过这篇文章,希望读者能够更好地理解装饰模式在Java中的实现,并能够在实际开发中灵活应用这种设计模式。如果你有任何疑问或想法,欢迎在下方留言!别忘了关注我们的公众号,获取更多有趣的编程知识和实用的代码技巧,我们期待与你的交流与分享!
在这里插入图片描述

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

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

相关文章

安防监控视频平台LntonAIServer视频监控管理平台裸土检测算法

LntonAIServer裸土检测算法代表了一种先进的土地监测技术,它利用人工智能的强劲能力,实现了对裸土区域的自动识别和实时监测。该算法的推出,为环境保护、农业管理以及城市规划等多个领域提供了创新的解决方案,其应用前景广阔&…

如何准备 Java API 文档以供下游对接

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119@qq.com] 📱个人微信:15279484656 🌐个人导航网站:www.forff.top 💡座右铭:总有人要赢。为什么不能是我呢? 专栏导…

QT:控件圆角设置、固定窗口大小

实现控件圆角度设置//使用的是setStyleSheet方法 //改变的控件是QTextEdit,如果你想改变其他控件,将QTextEdit进行更换 this->setStyleSheet("QTextEdit{background-color:#FFFFFF;border-top-left-radius:15px;border-top-right-radius:15px;bo…

是否掌握数据结构对于IT职业发展至关重要?

算法跟代码实现有时候是两回事,在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「数据结构的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!&#…

Chat2DB新推Chat2Excel,让数据对话跃然纸上

Excel 智能问答 Chat2Excel 1. 创建新聊天 点击左侧AI对话,进入对话界面。点击加号""按钮以开始一个新的对话。 新建对话选择表格类型, 选择上传excel文档。 双击对话名称可以修改对话名称。现在我们就可以开始针对于Excel进行智能问答了。 2. 智能…

智能小家电的跨境渠道有哪些?入驻百思买还是选择做亚马逊?——WAYLI威利跨境助力商家

在全球化贸易背景下,智能小家电企业面临机遇与挑战。消费者追求高品质生活,智能小家电市场需求旺盛,跨境销售成为拓展市场、提升品牌影响力的关键。选择合适的跨境渠道至关重要。以下是智能小家电跨境销售的主要渠道,并深入分析了…

layui 乱入前端

功能包含 本实例代码为部分傻瓜框架,插入引用layui。因为样式必须保证跟系统一致,所以大部分功能都是自定义的。代码仅供需要用layui框架,但原项目又不是layui搭建的提供解题思路。代码较为通用 自定义分页功能自定义筛选列功能行内编辑下拉、…

【探索Linux】P.43(网络层 —— IP协议)

阅读导航 引言一、IP协议基本概念二、IP协议头格式三、网段划分1. 网络号和主机号2. 引入子网掩码(1)基本概念(2)默认子网掩码(3)子网掩码的作用(4)子网掩码与IP地址的结合&#xff…

国内NAT服务器docker方式搭建rustdesk服务

前言 如果遇到10054,就不要设置id服务器!!! 由于遇到大带宽,但是又贵,所以就NAT的啦,但是只有ipv4共享和一个ipv6,带宽50MB(活动免费会升130MB~) https://bigchick.xyz/aff.php?aff322 月付-5 循环 :CM-CQ-Monthly-5 年付-60循环:CM-CQ-Annually-60官方…

Prometheus安装部署

文章目录 1.Prometheus(普罗米修斯)安装部署1.1部署环境准备1.2部署prometheus1.3主机数据展示 2.Grafana安装部署2.1部署Grafana2.2配置Grafana数据源2.2配置Grafana仪表板 3.AlertManager安装部署3.1部署alertmanager3.2告警邮件发送配置3.3测试邮件告警效果3.4自定义邮件告警…

昇思25天学习打卡营第9天|RNN实现情感分类

第十天的不小心把第九天的覆盖了。现在重新补上。 情感分类是自然语言处理中的经典任务,是典型的分类问题。输入一句话,然后去语义理解这句话是褒义贬义还是中性的。不同的情感语境下理解的大基调是不同的。 RRN情感分类也是一个分类模型,是…

多态、接口、类练习题

代码: public static void main(String[] args) {Person2 personnew Person2("唐僧",new Horse());person.passRiver();person.onRoad();} 接口: interface Vehicles{public void work(); } lass Horse implements Vehicles{Overridepubli…

外星人入侵_计分

外星人入侵_计分 1添加Play按钮1.1创建Button类1.2在屏幕上绘制按钮1.3开始游戏1.4 重置游戏1.5 将Play按钮切换到非活动状态1.6隐藏光标 2提高等级2.1修改速度设置2.2重置速度 3计分3.1显示得分3.2创建记分牌3.3在外星人被消灭时更新得分3.4将消灭的每个外星人的点数都计入得分…

TortoiseSVN迁移到本地git

TortoiseSVN迁移到本地git 文章目录 TortoiseSVN迁移到本地git0 背景1 环境准备2 SVN库迁移到VisualSVN2.1 导出dump2.2 将dump文件灌入VisualSVN2.3 获取SVN仓最新URL 3 迁移到Git库中4 迁移分支到Git库 0 背景 之前在前东家工作都是采用git进行项目管理,高效便捷…

Redis实战篇(黑马点评)笔记总结

一、配置前后端项目的初始环境 前端: 对前端项目在cmd中进行start nginx.exe,端口号为8080 后端: 配置mysql数据库的url 和 redis 的url 和 导入数据库数据 二、登录校验 基于Session的实现登录(不推荐) &#xf…

Ruby、Python、Java 开发者必备:Codigger之软件项目体检

在编程的广阔天地里,Ruby、Python 和 Java 开发者们各自凭借着独特的语言特性,构建着精彩纷呈的应用世界。然而,无论使用哪种语言,确保项目的高质量始终是至关重要的目标。而 Codigger 项目体检则成为了实现这一目标的得力助手&am…

React——配置环境、ES6语法补充、Components

文章目录 架构设计前置知识DOM树 配置环境安装 create-react-app安装两个插件创建安装 nodejs仍然无法创建 下次需要创建新项目就使用这三行命令安装 bootstrap使用 bootstrap 包画图追求写 jsx短路原则绑定函数快捷键修改变量名箭头函数简写删除无用的文件写组件调用组件使用 …

人工智能与机器学习原理精解【11】

文章目录 广义线性模型基础理论泊松分布的基本公式一、基本公式二、泊松分布的特点三、泊松分布的应用场景四、泊松分布与二项分布的关系五、总结 泊松回归例子1例子背景模型设定数据收集模型拟合结果解释预测应用场景 泊松回归例子2背景数据准备模型设定模型拟合结果解释预测 …

Prometheus-部署

Prometheus-部署 Server端安装配置部署Node Exporters监控系统指标监控MySQL数据库监控nginx安装grafana Server端安装配置 1、上传安装包,并解压 cd /opt/ tar xf prometheus-2.30.3.linux-amd64.tar.gz mv prometheus-2.30.3.linux-amd64 /usr/local/prometheus…

TypeScript 简介及安装

文档 typeScript官网中文文档:https://www.tslang.cn/index.html中文文档(简洁点):https://typescript.bootcss.comMDN 概述 TypeScript 是以JavaScript为基础构建的语言。 TypeScript 是一个为 JavaScript 添加静态类型检查的编程语言。 TypeScrip…