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

news/2024/10/18 20:13:29/

目录

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

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 抽象类表示可被装饰的组件:

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

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

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

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

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

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

javascript">   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)使用方式如下:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

javascript">   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.ppmy.cn/news/1538796.html

相关文章

ArgoCD 与 Amazon EKS 结合实战

在当今快速发展的云原生世界中,持续部署和基础设施即代码已成为不可或缺的实践。ArgoCD 作为一个强大的 Kubernetes 持续部署工具,结合 Amazon EKS (Elastic Kubernetes Service) 这一成熟的托管 Kubernetes 服务,为开发者和运维团队提供了一个强大的组合。本文将深入探讨如…

IP报文格式、IPv6概述

IPv4报文格式 IPv4报文首部长度至少为20字节(没有可选字段和填充的情况下)&#xff0c;下面来逐一介绍首部各个字段的含义 Version版本&#xff1a;表示采用哪一种具体的IP协议&#xff0c;对于IPv4来说该字段就填充4以表示&#xff0c;如果是IPv6就填充6IHL首部长度&#xff…

3.stable-diffusion1.10.0精准控制图-ControlNet插件的安装

安装 Controlnet 插件 注&#xff1a;从网址安装可以保证插件的更新能在 WebUI 中自动显示&#xff0c;如果是下载压缩包文件放进根目录&#xff0c;就无法自动更新。下面执行网址安装。 打开 WebUI&#xff0c;点击“扩展”选项卡&#xff0c;选择“从网址安装”&#xff0c;…

数据结构 ——— C语言实现带哨兵位双向循环链表

目录 前言 无哨兵位单向不循环链表的缺陷 带哨兵位双向循环链表的概念 带哨兵位双向循环链表的结构 带哨兵位双向循环链表逻辑结构示意图​编辑 实现带哨兵位双向循环链表的准备工作 实现带哨兵位双向循环链表 1. 创建新节点 2. 初始化哨兵位 3. 定义哨兵位指针 4. …

SRS服务器搭建

1、配置 listen 1935; max_connections 1000; #srs_log_tank file; #srs_log_file ./objs/srs.log; daemon on; http_api { enabled on; listen 1985; } http_server { enabled on; listen 808…

线性代数入门指南

在数学的广袤领域中&#xff0c;线性代数犹如一座神秘而又充满魅力的殿堂&#xff0c;等待着初学者去探索。当你踏入线性代数的大门&#xff0c;便开启了一段充满挑战与惊喜的知识之旅。 线性代数是什么呢&#xff1f;简单来说&#xff0c;它是一门研究线性方程组、向量空间、线…

【Linux】Linux进程基础

1.进程介绍与概念 进程的本质是在计算机内存中运⾏的程序&#xff0c;但是这⼀个概念太过于⼴泛 每个应用程序运行于现代操作系统之上时&#xff0c;操作系统会提供一种抽象&#xff0c;好像系统上只有这个程序在运行&#xff0c;所有的硬件资源都被这个程序在使用。这种假象…

AI学习指南深度学习篇-迁移学习(Transfer Learning)简介

AI学习指南深度学习篇-迁移学习&#xff08;Transfer Learning&#xff09;简介 引言 在快速发展的人工智能 (AI) 和深度学习领域&#xff0c;数据和计算资源的需求不断增加。虽然深度学习模型在图像识别、自然语言处理等领域取得了巨大成功&#xff0c;但构建这些模型需要大…