前端开发设计模式——装饰器模式

目录

一、装饰器模式的定义和特点

1.定义

2.特点

二、装饰器模式的实现方式

1.在原生JS中实现(以类的形式为例)

2、在Vue中实现(以指令和混入为例)

        2.1、指令方式实现装饰功能

        2.2、混入方式实现装饰功能

三、装饰器模式的使用场景

1.用户界面增强

2.权限管理

3.数据处理与展示

四、装饰器模式的优点

1.灵活性

2.遵循开闭原则

3.单一职责原则的体现

五、装饰器模式的缺点

1.增加复杂性

2.可能影响性能

六、装饰器模式的注意事项

1.接口的稳定性

2.避免过度装饰

3.装饰器顺序


一、装饰器模式的定义和特点

1.定义

        装饰器模式是一种结构型设计模式,它允许在不改变对象结构的情况下,动态地给一个对象添加一些额外的功能。这个模式通过创建装饰类来包装原始对象,装饰类与原始对象实现相同的接口,从而可以在运行时根据需要组合不同的装饰类来扩展对象的功能。

2.特点

        保持接口一致性:装饰类和被装饰类实现相同的接口,这样在使用装饰后的对象时,对于客户端来说,它看起来仍然是原始类型的对象,客户端代码不需要进行修改就可以使用被装饰后的对象。

        动态扩展性:可以在运行时动态地添加或移除装饰,根据不同的需求灵活组合装饰类,以实现不同的功能组合。

        单一职责原则:每个装饰类都专注于一个特定的功能扩展,这样代码的可维护性和可读性更高。

二、装饰器模式的实现方式

1.在原生JS中实现(以类的形式为例)

        (1)首先定义一个基础接口或者抽象类(在 JavaScript 中可以使用抽象类的概念来模拟)。例如,定义一个 Component 抽象类表示可被装饰的组件:

   class Component {operation() {throw new Error('Abstract method must be implemented');}}

        (2)然后创建一个具体的组件类实现这个接口,例如 ConcreteComponent:

   class ConcreteComponent extends Component {operation() {console.log('ConcreteComponent operation');}}

        (3)接着定义装饰器类,装饰器类也继承自 Component 抽象类,并且在构造函数中接收一个 Component 类型的实例,例如 Decorator:

   class Decorator extends Component {constructor(component) {super();this.component = component;}operation() {this.component.operation();}}

        (4)最后创建具体的装饰器类,例如 ConcreteDecoratorA 和 ConcreteDecoratorB,它们在 operation 方法中添加额外的功能:

   class ConcreteDecoratorA extends Decorator {operation() {console.log('ConcreteDecoratorA before operation');super.operation();console.log('ConcreteDecoratorA after operation');}}class ConcreteDecoratorB extends Decorator {operation() {console.log('ConcreteDecoratorB before operation');super.operation();console.log('ConcreteDecoratorB after operation');}}

        (5)使用方式如下:

   const component = new ConcreteComponent();const decoratedComponentA = new ConcreteDecoratorA(component);const decoratedComponentAB = new ConcreteDecoratorB(decoratedComponentA);decoratedComponentAB.operation();

2、在Vue中实现(以指令和混入为例)

        2.1、指令方式实现装饰功能

                假设我们有一个基础的 Vue 组件,例如一个简单的按钮组件:

   <template><button @click="handleClick">Base Button</button></template><script>export default {methods: {handleClick() {console.log('Button clicked');}}};</script>

                我们可以创建一个指令来装饰这个按钮组件,例如给按钮添加权限验证功能的指令。首先定义指令:

   Vue.directive('permission - check', {inserted: function (el, binding) {// 假设这里有一个权限验证逻辑,比如根据用户权限角色判断是否有点击按钮的权限const hasPermission = checkPermission(binding.value);if (!hasPermission) {el.disabled = true;}}});

                这里的 checkPermission 是一个假设的函数,用于检查权限。然后在组件中使用这个指令:

   <template><button @click="handleClick" v - permission - check="'button - click - permission'">Base Button</button></template>
        2.2、混入方式实现装饰功能

                假设我们有一个基础的显示数据的 Vue 组件:

   <template><div>{{ data }}</div></template><script>export default {data() {return {data: 'Base Data'};}};</script>

                我们可以创建一个混入(mixin)来装饰这个组件,例如给数据添加格式化功能的混入。定义混入:

   const formatDataMixin = {computed: {formattedData() {return format(this.data);}}};

                这里的 format 是一个假设的函数,用于格式化数据。然后在组件中使用这个混入:

   export default {mixins: [formatDataMixin],data() {return {data: 'Base Data'};},computed: {// 可以在组件中继续使用原始数据或者新的格式化后的数据combinedData() {return this.data +'(' + this.formattedData + ')'}}};

三、装饰器模式的使用场景

1.用户界面增强

        在前端界面开发中,常用于给用户界面组件添加额外功能。例如,给输入框组件添加验证功能,如必填项验证、格式验证等。可以创建一个 ValidationDecorator 来装饰输入框组件,在用户输入数据时进行验证,而不需要修改输入框组件的原始代码。

2.权限管理

        对于一些页面元素,如菜单、按钮等,可以使用装饰器模式添加权限检查功能。例如,创建一个 PermissionDecorator,它在渲染组件之前检查用户是否具有访问该组件所代表功能的权限,如果没有权限则隐藏或禁用该组件。

3.数据处理与展示

        在处理从服务器获取的数据时,可以使用装饰器模式对数据进行加工和美化后再展示。例如,创建一个 FormattingDecorator,如果获取到的是日期数据,可以将其格式化为更友好的显示形式,如将时间戳转换为指定格式的日期字符串。

四、装饰器模式的优点

1.灵活性

        可以根据具体需求动态地组合装饰器,添加或移除功能。例如,在不同的用户角色或业务场景下,可以灵活地给组件添加不同的功能装饰,而不需要重新编写组件的核心代码。

2.遵循开闭原则

        不需要修改原始类的代码就可以扩展其功能。这使得在项目维护和功能迭代过程中,代码的稳定性更高。当需要添加新功能时,只需创建新的装饰类并进行组合即可。

3.单一职责原则的体现

        每个装饰类只负责一个特定的功能扩展,使得代码结构更加清晰,易于理解和维护。开发人员可以专注于每个功能的实现,降低了代码的复杂性。

五、装饰器模式的缺点

1.增加复杂性

        如果过度使用装饰器模式,会导致代码结构变得复杂,尤其是在有多个装饰器层层嵌套的情况下。这可能会使代码的调试和理解变得困难,对于新加入项目的开发人员来说,需要花费更多的时间来理解装饰器之间的关系。

2.可能影响性能

        在某些情况下,由于装饰器的层层嵌套,可能会导致额外的函数调用开销,从而影响性能。特别是在对性能要求较高的应用场景中,需要谨慎使用装饰器模式并进行性能优化。

六、装饰器模式的注意事项

1.接口的稳定性

        装饰类和被装饰类所实现的接口(或遵循的协议)应该保持稳定。如果接口发生变化,可能会导致装饰器与被装饰对象之间的不兼容,从而需要修改大量的代码。

2.避免过度装饰

       要谨慎使用装饰器模式,避免创建过多不必要的装饰器以及过度嵌套装饰器。在设计阶段就应该评估功能需求,尽量保持装饰器结构的简洁性,以减少复杂性和性能问题。

3.装饰器顺序

         在组合多个装饰器时,装饰器的顺序可能会影响最终的结果。例如,一个先进行数据加密再进行数据压缩的装饰器顺序,与先进行数据压缩再进行数据加密的顺序,得到的结果可能是不同的。因此,在使用装饰器模式时,需要明确装饰器的顺序以及其对功能的影响。

        关于装饰器模式的分享就到此结束了,如果对于其他设计模式有兴趣的话,可以点击右下角“专栏目录”查看更多设计模式

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

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

相关文章

基于方块编码的图像压缩matlab仿真,带GUI界面

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 编码单元的表示 4.2编码单元的编码 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 下图是随着方块大小的变化&#xff0c;图像的压缩率以及对应的图像质量指标PSN…

PDF处理技巧:Windows电脑如何选择合适的 PDF 编辑器

您可以阅读本文以了解用于在 PC 上编辑 PDF 的顶级免费软件&#xff0c;而无需花费任何费用即可轻松进行快速编辑、拆分、合并、注释、转换和共享您的 PDF。 PDF 或可移植文档文件是由 Adobe 创建的一种多功能文件格式。它可以帮助您轻松可靠地交换文档&#xff0c;无论相关方…

TCN-Transformer时间序列预测(多输入单预测)——基于Pytorch框架

1 数据集介绍 我们使用的数据集包含以下几个重要的属性&#xff1a; date&#xff08;日期&#xff09; open&#xff08;开盘价&#xff09; high&#xff08;最高价&#xff09; low&#xff08;最低价&#xff09; close&#xff08;收盘价&#xff09; pre_close&…

IDE启动失败

报错&#xff1a;Cannot connect to already running IDE instance. Exception: Process 24,264 is still running 翻译&#xff1a;无法连接到已运行的IDE实例。异常:进程24,264仍在运行 打开任务管理器&#xff0c;找到PID为24264的CPU线程&#xff0c;强行结束即可。 【Ct…

EXCEL_光标百分比

Public Sub InitCells()Dim iSheet As LongFor iSheet Sheets.Count To 1 Step -1Sheets(iSheet).ActivateActiveWindow.Zoom 85ActiveWindow.ScrollRow 1ActiveWindow.ScrollColumn 1Sheets(iSheet).Range("A1").ActivateNext iSheetEnd Sub对日项目中的文档满天…

CSS 布局——清除浮动 (二)

目录 1. 清除浮动 2. 清除浮动本质 3. 清除浮动 4. 清除浮动方法 4.1 额外标签法 4.1.1 总结 4.2 父级添加 overflow 4.3 after 伪元素法 4.4 双伪元素清除浮动 5 总结 1. 清除浮动 这是上面的源代码&#xff1a; <!DOCTYPE html> <html lang"en"&…

【FPGA开发】Modelsim如何给信号分组

前面已经发布过了一篇关于 Modelsim 的入门使用教程&#xff0c;针对的基本是只有一个源文件加一个仿真tb文件的情况&#xff0c;而实际的工程应用中&#xff0c;往往是顶层加多个底层的源文件结构&#xff0c;如果不对信号进行一定的分组&#xff0c;就会显得杂乱不堪&#xf…

第33次CCF计算机软件能力认证-第4题十滴水

题干&#xff1a; 十滴水是一个非常经典的小游戏。 小 C C C 正在玩一个一维版本的十滴水游戏。 我们通过一个例子描述游戏的基本规则。 游戏在一个 1 c 1c 1c 的网格上进行&#xff0c;格子用整数 x ( 1 ≤ x ≤ c ) x(1≤x≤c) x(1≤x≤c) 编号&#xff0c;编号从左往…

Python学习-函数

函数 文章目录 函数定义与调用参数传递内存分析返回值参数定义默认值参数个数可变的参数关键字参数 变量的作用域 匿名函数基本语法示例lambda与排序高阶函数map函数reduce函数filter函数 多关键字排序 定义与调用 函数可以嵌套用 先定义后调用 def calc(a,b):cabreturn cre…

一台电脑轻松接入CANFD总线_来可CNA板卡介绍

在工业控制领域&#xff0c;常常使用的总线技术有CAN(FD)、RS-232、RS-485、Modbus、Profibus、Profinet、EtherCAT等。RS-485以其长距离通信能力著称&#xff0c;Modbus广泛应用于PLC等设备&#xff0c;EtherCAT则以其低延迟和高实时性在自动化系统中备受青睐。 其中&#xff…

Java虚拟机(JVM)介绍

**Java虚拟机&#xff08;JVM&#xff09;**是Java平台的核心组件&#xff0c;它提供了一个运行时环境&#xff0c;使得Java程序可以在不同的操作系统和硬件平台上运行而无需修改。 JVM的架构 JVM主要由以下几个部分组成&#xff1a; 类加载器&#xff08;Class Loader&#xf…

对后端返回的日期属性进行格式化(扩展 Spring MVC 的消息转换器)

格式化之前 格式化之后&#xff1a; 解决方式 方式一 在属性中加上注解&#xff0c;对日期进行格式化 JsonFormat(pattern "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTime;//JsonFormat(pattern &quo…

小白必看web专题!PHP-WebShell免杀(基础版)!!真的很简单!(全网最详细版本)

大家好&#xff0c;我是Dest1ny&#xff01; 最近一直在搞辅导啥的&#xff0c;所以没啥时间搞写&#xff5e; 也谢谢大家一直的点赞&#xff0c;今天特意把之前的web专题再发一个。 废话不多说&#xff0c;我们直接开始&#xff01; CLASS-1 WebShell免杀测试 渊龙Sec团队导…

「Ubuntu」根目录存储空间不足

Linux系统不同于 Windows系统&#xff0c;复杂的文件系统常常让人头疼&#xff0c;特别是动不动就存储空间不足&#xff0c;简单的清空回收站根本不管用&#xff0c;在此推荐一个绝对好用的方法&#xff0c;并且还可以多学习一条 Linux命令 1、du 使用方法 通过使用命令 du&am…

Ubuntu24.04 安装 NCAR Command Language(NCL)

目录 一般直接在Terminal中使用apt安装命令即可&#xff0c; 出现这样的问题&#xff0c; 如何解决这个问题呢&#xff1f; 一般直接在Terminal中使用apt安装命令即可&#xff0c; sudo apt install ncl-ncarg 但是&#xff0c;由于 Ubuntu 版本较新 Ubuntu 24.04&#xff…

【Next.js 入门教程系列】07-身份验证

原文链接 CSDN 的排版/样式可能有问题&#xff0c;去我的博客查看原文系列吧&#xff0c;觉得有用的话&#xff0c; 给我的库点个star&#xff0c;关注一下吧 上一篇【Next.js 入门教程系列】06-上传文件 身份验证 本篇包括以下内容: Setting up Next AuthConfiguring the G…

基于Spring Boot的医疗病历交互系统开发指南

第2章 设计技术与开发环境 2.1 相关技术介绍 2.1.1 B/S模式分析 C/S模式主要由客户应用程序(Client)、服务器管理程序(Server)和中间件(middleware)三个部件组成。客户应用程序是系统中用户与数据组件交互。服务器程序负责系统资源&#xff0c;如管理信息数据库的有效管理&…

使用Docker搭建WAF-开源Web防火墙VeryNginx

1、说明 VeryNginx 基于 lua_nginx_module(openrestry) 开发,实现了防火墙、访问统计和其他的一些功能。 集成在 Nginx 中运行,扩展了 Nginx 本身的功能,并提供了友好的 Web 交互界面。 文章目录 1、说明1.1、基本概述1.2、主要功能1.3、应用场景2、拉取镜像3、配置文件4、…

kafka-manager修改zookeeper端口号后启动仍然连接2181端口

问题描述&#xff1a; zookeeper默认端口号修改为了2182&#xff0c;kafka-manager的配置文件application.conf中也已经修改了zkhosts为新的端口号&#xff0c;然而启动kafka-manger时报错连接连接超时&#xff0c;发现连接的还是2181端口&#xff0c;很奇怪&#xff1f;&…

【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可…