业务代码中如何使用装饰器模式?

装饰器模式(Decorator Pattern)介绍

装饰器模式(Decorator Pattern)是一种结构型设计模式,我们可以动态地给一个对象添加额外的职责。而不是通过继承增加子类的方式来扩展对象的功能,装饰器模式使用组合的方式来增强对象的功能,这有助于保持类的职责单一,提高了类的复用性和灵活性。

装饰器模式通常涉及以下角色:

  • • 组件(Component)接口:定义了一个对象接口,可以动态地给这些对象添加职责。

  • • 具体组件(Concrete Component):实现了组件接口的对象,这是我们要动态添加职责的对象。

  • • 装饰器(Decorator)类:实现了组件接口的抽象类,并持有一个组件接口的引用。这个类的任务是定义那些可以动态添加的职责。

  • • 具体装饰器(Concrete Decorator):实现了装饰器类的具体类,负责给组件添加新的职责。

优缺点

优点:

  • • 扩展对象功能:装饰器模式提供了一种灵活的替代方案来扩展对象的功能,比继承更灵活。

  • • 动态添加职责:可以动态地添加或删除对象的职责。

  • • 复合而非继承:通过使用组合而非继承的方式,避免了在层级关系上造成静态的继承关系,提高了代码的可复用性和灵活性。

缺点:

  • 增加系统复杂性:使用大量的小类,可能会增加系统的复杂度。

  • 多层装饰比较复杂:当装饰链过长时,会增加系统的复杂度,并且调试时可能会带来不便。

Spring Boot中业务代码示例

假设我们有个下单流程计算价格,现在我们需要新增一个打折优惠。怎么不修改原来代码巧妙的增加我们的功能呢?通过装饰器模式将不同的折扣策略作为装饰层动态添加到订单处理流程中。这样,我们可以在不修改现有类的情况下,灵活地添加或修改折扣策略。

订单接口

首先,定义一个订单服务接口,这是我们的组件接口:

public interface OrderService {double applyDiscount(double orderTotal);
}

实现一个基本的订单服务:

@Component
public class SimpleOrderService implements OrderService {@Overridepublic double applyDiscount(double orderTotal) {// 默认情况下,没有任何折扣return orderTotal;}
}

装饰器实现

接着,我们创建一个装饰器抽象类:

@Component
public abstract class OrderServiceDecorator implements OrderService {@Resourceprotected OrderService simpleOrderService;@Overridepublic double applyDiscount(double orderTotal) {return simpleOrderService.applyDiscount(orderTotal);}
}

定义不同的折扣策略作为装饰器:

@Component
public class PercentageDiscountDecorator extends OrderServiceDecorator {@Overridepublic double applyDiscount(double orderTotal) {// 折扣率double discountRate = 0.2;double discount = orderTotal * discountRate;return super.applyDiscount(orderTotal - discount);}
}

整体结构如下

图片

测试一下

@SpringBootApplication
public class DecoratorPatternApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(DecoratorPatternApplication.class, args);OrderService percentageService = context.getBean(PercentageDiscountDecorator.class);double orderTotal = 300.0;double discountedTotal = percentageService.applyDiscount(orderTotal);System.out.println("Discounted order total: " + discountedTotal);}
}

图片

在这个例子中,通过PercentageDiscountDecorator 添加了百分比折扣。通过这种方式,我们可以根据需要灵活地组合和应用不同的折扣策略,而不必更改现有的订单服务代码。这种方法提高了代码的可维护性和扩展性,同时也保持了业务逻辑的清晰性。

与策略模式区别

之前分享过策略模式的实现:如何在业务代码中优雅的使用策略模式

我们回顾下策略模式的特征:策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以互相替换。策略模式让算法独立于使用它的客户端而变化,即分离了算法的定义和使用,客户端代码通过依赖注入的方式选择使用哪一种策略。

在我们上面的示例中,如果使用装饰器模式,我们可以动态地为订单服务添加额外的功能(如折扣),而每个装饰器都可以独立地添加额外的职责。

而如果使用策略模式来处理折扣,我们可能会定义一个折扣策略接口,然后为每种折扣定义一个具体的策略类。客户端代码决定使用哪一种折扣策略,并将其应用于订单总额上。这里,策略是静态选择的,并且一次只能应用一个策略。

装饰器模式强调的是如何动态地添加职责,而策略模式强调的是如何封装算法和行为,并在它们之间切换。

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

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

相关文章

[N1CTF 2018]eating_cms 不会编程的崽

题倒是不难,但是实在是恶心到了。 上来就是登录框,页面源代码也没什么特别的。寻思抓包看一下,数据包直接返回了sql查询语句。到以为是sql注入的题目,直到我看到了单引号被转义。。。挺抽象,似乎sql语句过滤很严格。又…

Java基础知识点之思维导图

一、走进Java编程世界 二、变量常量和运算符 三、if选择结构 四、switch选择结构 五、while循环结构 六、for循环结构 七、数组 八、类与对象 九、深入循环结构 十、类的无参方法 十一、类的带参方法 十二、字符串

读已提交隔离级别下竟然有间隙锁

业务背景 广告主痛点的为进行一次全媒体联合投放,若投放10个媒体,需要制作和上传10个创意、50张不同尺寸和出血区要求的图片和视频素材、近100个元素,投放成本极高。这也是制约部分用户使用新产品投放的原因。 因此进行升级。以三个创意为例…

Prometheus添加nginx节点显示不支持stub_status 解决办法

1、我们在使用Prometheus监控添加nginx节点监控的时候,在被监控节点的nginx配置文件中添加下面的模块 server { listen 80; server_name localhost; location /stub_status { stub_status on; access_log off; …

微服务技术栈SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式(四):消息队列MQ

文章目录 一、消息队列MQ二、RabbitMQ2.1 单机部署2.2 消息模型 三、SpringAMAP3.1 简单消息队列3.2 工作消息队列3.3 发布-订阅模型:FanoutExchange 广播交换机3.4 发布-订阅模型:DirectExchange 路由交换机3.5 发布-订阅模型:TopicExchange…

Day29:安全开发-JS应用DOM树加密编码库断点调试逆向分析元素属性操作

目录 JS原生开发-DOM树-用户交互 JS导入库开发-编码加密-逆向调试 思维导图 JS知识点: 功能:登录验证,文件操作,SQL操作,云应用接入,框架开发,打包器使用等 技术:原生开发&#x…

推房子游戏c++

这段代码是一个推箱子游戏的实现。游戏中有一个地图,地图上有墙壁、人、箱子和目标位置。玩家通过键盘输入WASD或方向键来控制人物的移动,目标是将所有的箱子推到相应的目标位置上。 代码中的dt数组表示地图,每个位置上的字符表示对应的元素…

c语言在线聊天室

c语言基于tcp和多线程的在线聊天室(c语言通讯系统)功能需求 1.实现多线程 2.构建socke套接字实现一对一通信 3.实现多个电脑的通信 4.数据传输加密和解密 5.多人实时聊天 6.具备群聊和私聊的功能 实现原理: 服务端公网Ip暴露,客户端端口随机分配,通过服务端公网IP连接,服务端…

【开源】SpringBoot框架开发免税店商城管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 功能模块设计2.2 研究方法 三、系统展示四、核心代码4.1 查询免税种类4.2 查询物品档案4.3 新增顾客4.4 新增消费记录4.5 审核免税 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的免税店商城管理系…

【文本编辑】Typora v1.8.6 绿色版

下载地址 Typora v1.8.6 绿色版 简介 Typora 是一款简洁、直观的跨平台 Markdown 编辑器,旨在提供优雅的写作体验。与传统的 Markdown 编辑器不同,Typora 提供所见即所得的编辑界面,使用户可以即时预览 Markdown 文档的渲染效果&#xff0…

prometheus 原理(架构,promql表达式,描点原理)

大家好,我是蓝胖子,提到监控指标,不得不说prometheus,今天这篇文章我会对prometheus 的架构设计,promql表达式原理和监控图表的绘图原理进行详细的解释。来让大家对prometheus的理解更加深刻。 架构设计 先来看看&am…

性能测试干2年,还不会这个技术点?

nmon是一种在AIX与各种Linux操作系统上广泛使用的监控与分析工具,记录的信息比较全面,结合nmon_analyzer工具产生数据文件与图形化结果。 nmon可监控的数据类型 内存使用情况、磁盘适配器、文件系统中的可用空间、CPU使用率等等数据信息 特点 ①占用…

Java零基础-数组的访问和遍历

哈喽,各位小伙伴们,你们好呀,我是喵手。 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。 我是一名后…

使用CSS制作动态的环形图/饼图

使用纯 CSS Animation conic-gradient 实现一个环形图。 饼图的实现思路和环形图一样&#xff0c;去掉中间的圆形遮盖 after 伪类元素即可。 一、构建基础样式 构建圆形节点和中间的遮盖元素。 <style>body {background-color: rgb(130, 226, 255);}.circle {top: 16…

持续更新 | 与您分享 Flutter 2024 年路线图

作者 / Michael Thomsen Flutter 是一个拥有繁荣社区的开源项目&#xff0c;我们致力于确保我们的计划公开透明&#xff0c;并将毫无隐瞒地分享从问题到设计规范的所有内容。我们了解到许多开发者对 Flutter 的功能路线图很感兴趣。我们往往会在一年中不断更改并调整这些计划&a…

Clock Verification IP

Clock Verification IP IP 参数及接口 IP 例化界面 相关函数 start_clock //产生时钟 <hierarchy_path>.IF.start_clockstop_clock //停止时钟 <hierarchy_path>.IF.stop_clockset_initial_value //设置时钟初始值为 0 <hierarchy_path>IF.set_initia…

Python和Google Colab进行卫星图像二维小波变化和机器学习

2D 小波分解是图像处理中的一种流行技术,使用不同的滤波器将图像分解为不同的频率分量(“近似”和“细节”系数)。该技术对于各种图像处理任务特别有用,例如压缩、去噪、特征提取和边缘检测。 在本文中,我们将演示如何在 Google Colab 中使用 Python 下载高分辨率样本卫星…

解决火狐浏览器访问地址受限制问题(This address is restricted)

问题如下图&#xff1a; This address is restrictedThis address uses a network port which is normally used for purposes other than Web browsing. Firefox has canceled the request for your protection. 此地址受到限制 此地址使用通常用于 Web 浏览以外的目的的网…

【Pytorch】进阶学习:基于矩阵乘法torch.matmul()实现全连接层

【Pytorch】进阶学习&#xff1a;基于矩阵乘法torch.matmul()实现全连接层 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448…

深入了解304缓存原理:提升网站性能与加载速度

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…