当前位置: 首页 > news >正文

小谈设计模式(7)—装饰模式

小谈设计模式(7)—装饰模式

  • 专栏介绍
    • 专栏地址
    • 专栏介绍
  • 装饰模式
    • 装饰模式角色
      • Component(抽象组件)
      • ConcreteComponent(具体组件)
      • Decorator(抽象装饰器)
      • ConcreteDecorator(具体装饰器)
    • 工作流程
      • 首先
      • 其次
      • 然后
      • 最后
    • Java代码实现
      • 代码分析
    • 优缺点分析
      • 优点
        • 符合开闭原则
        • 可以动态地添加/删除功能
        • 遵循单一职责原则
        • 装饰器类与具体组件类独立
      • 缺点
        • 可能产生过多的具体装饰器类
        • 装饰器与组件类的接口不一致
    • 总结

专栏介绍

专栏地址

link

专栏介绍

主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。希望各位可以监督我,我们一起学习进步,加油,各位。
在这里插入图片描述

装饰模式

装饰模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地向一个对象添加额外的功能,而不需要修改其原始类。通过将对象包装在装饰器类中,你可以在不改变现有对象结构的情况下,逐步地添加功能。

装饰模式角色

在这里插入图片描述

Component(抽象组件)

定义了具体组件和装饰器的共同接口,可以是抽象类或接口。

ConcreteComponent(具体组件)

实现了抽象组件定义的接口,是被装饰的原始对象。

Decorator(抽象装饰器)

包含一个指向具体组件的引用,并实现了抽象组件定义的接口。

ConcreteDecorator(具体装饰器)

通过装饰器对具体组件进行扩展或修改,添加额外的功能。

在这里插入图片描述

工作流程

首先

定义一个抽象组件(Component),它声明了具体组件和装饰器共同的接口方法。

其次

创建一个具体组件(ConcreteComponent),它实现了抽象组件的接口方法,是被装饰的原始对象。

然后

创建一个抽象装饰器(Decorator),它也实现了抽象组件的接口方法,并包含一个指向具体组件的成员变量(通常为抽象组件类型),用于持有被装饰的对象。

最后

创建具体装饰器(ConcreteDecorator),它继承自抽象装饰器,并在装饰器的基础上添加了额外的功能。具体装饰器中通常会重写抽象组件的接口方法,以在调用前后进行额外的处理,然后再调用被装饰对象的相应方法。
在这里插入图片描述

Java代码实现

// Step 1: 定义抽象组件
interface Component {void operation();
}// Step 2: 创建具体组件
class ConcreteComponent implements Component {public void operation() {System.out.println("执行具体组件的操作");}
}// Step 3: 创建抽象装饰器
abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}public void operation() {component.operation();}
}// Step 4: 创建具体装饰器
class ConcreteDecorator extends Decorator {public ConcreteDecorator(Component component) {super(component);}public void operation() {// 在调用具体组件操作前进行额外处理System.out.println("在调用具体组件操作前进行额外处理");// 调用具体组件的操作super.operation();// 在调用具体组件操作后进行额外处理System.out.println("在调用具体组件操作后进行额外处理");}
}// 使用装饰模式
public class Main {public static void main(String[] args) {// 创建具体组件对象Component component = new ConcreteComponent();// 创建具体装饰器对象,并将具体组件对象传入Component decorator = new ConcreteDecorator(component);// 调用装饰后的操作decorator.operation();}
}

代码分析

Component 是抽象组件接口,ConcreteComponent 是具体组件类,实现了抽象组件接口的方法。Decorator 是抽象装饰器类,实现了抽象组件接口,并持有一个抽象组件类型的成员变量。ConcreteDecorator 是具体装饰器类,继承自抽象装饰器类,并重写了操作方法,在调用前后添加了额外处理。

在主函数中,先创建具体组件对象ConcreteComponent,然后将其传入具体装饰器对象ConcreteDecorator 的构造函数中,用装饰器包装具体组件。最后调用装饰后的操作,会按照一定的顺序执行额外处理和具体组件操作。

优缺点分析

优点

符合开闭原则

可以在不修改现有代码的情况下,通过新增装饰器类来扩展对象的功能。

可以动态地添加/删除功能

可以根据需要动态地添加或删除对象的功能,组合不同的装饰器实现不同的行为组合。

遵循单一职责原则

具体的组件类只负责核心功能,具体的装饰器类只关注附加的功能,各个类职责明确,可维护性高。

装饰器类与具体组件类独立

装饰器类与具体组件类之间是松耦合的关系,可以独立变化,增加或删除装饰器不会影响其他组件的行为。

缺点

可能产生过多的具体装饰器类

如果系统中有很多功能需要扩展,可能会导致产生大量的具体装饰器类,增加系统的复杂性。

装饰器与组件类的接口不一致

在装饰器模式中,装饰器类和具体组件类的接口不一致,导致客户端需要区分调用。
在这里插入图片描述

总结

装饰模式提供了一种灵活的、可扩展的方式来修改对象的功能,同时保持了简单的接口和代码的可维护性。但是需要权衡好扩展的复杂度和对象接口的一致性。

相关文章:

小谈设计模式(7)—装饰模式

小谈设计模式(7)—装饰模式 专栏介绍专栏地址专栏介绍 装饰模式装饰模式角色Component(抽象组件)ConcreteComponent(具体组件)Decorator(抽象装饰器)ConcreteDecorator(具…...

nginx 多层代理 + k8s ingress 后端服务获取客户真实ip 配置

1.nginx http 七层代理 修改命令空间: namespace: nginx-ingress : configmap:nginx-configuration kubectl get cm nginx-configuration -n ingress-nginx -o yaml添加如上配置 compute-full-forwarded-for: “true” forwarded-for-header: X-Forwa…...

6种最常用的3D点云语义分割AI模型对比

由于增强现实/虚拟现实的发展及其在计算机视觉、自动驾驶和机器人领域的广泛应用,点云学习最近引起了人们的关注。 深度学习已成功用于解决 2D 视觉问题,然而,由于其处理面临独特的挑战,深度学习技术在点云上的使用仍处于起步阶段…...

UG NX二次开发(C#)-获取UI中选择对象的handle值

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、设计一个简单的UI界面3、创建工程项目4、测试结果1、前言 我在哔哩哔哩的视频中看到有人问我如何获取UI选择对象的Handle,本来想把Tag、Taggedobject、Handle三者的关系讲一下,然后看…...

win10,WSL的Ubuntu配python3.7手记

1.装linux 先在windows上安装WSL版本的Ubuntu Windows10系统安装Ubuntu子系统_哔哩哔哩_bilibili (WSL2什么的一直没搞清楚) 图形界面会出一些问题,注意勾选ccsm出的界面设置 win10安装Ubuntu16.04子系统,并开启桌面环境_win…...

02-Zookeeper实战

上一篇:01-Zookeeper特性与节点数据类型详解 1. zookeeper安装 Step1: 配置JAVA环境,检验环境: java -versionStep2: 下载解压 zookeeper wget https://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeepe…...

【C语言深入理解指针(1)】

1.内存和地址 1.1内存 在讲内存和地址之前,我们想有个⽣活中的案例: 假设有⼀栋宿舍楼,把你放在楼⾥,楼上有100个房间,但是房间没有编号,你的⼀个朋友来找你玩,如果想找到你,就得挨…...

模拟实现简单的通讯录

前言:生活中处处都会看到或是用到通讯录,今天我们就通过C语言来简单的模拟实现一下通讯录。 鸡汤:跨越山海,终见曙光! 链接:gitee仓库:代码链接 目录 主函数声明部分初始化通讯录实现扩容的函数增加通讯录所…...

rabbitMQ死信队列快速编写记录

文章目录 1.介绍1.1 什么是死信队列1.2 死信队列有什么用 2. 如何编码2.1 架构分析2.2 maven坐标2.3 工具类编写2.4 consumer1编写2.5 consumer2编写2.6 producer编写 3.整合springboot3.1 架构图3.2 maven坐标3.3 构建配置类,创建exchange,queue&#x…...

数位dp,338. 计数问题

338. 计数问题 - AcWing题库 给定两个整数 a 和 b,求 a 和 b 之间的所有数字中 0∼90∼9 的出现次数。 例如,a1024,b1032,则 a 和 b 之间共有 9 个数如下: 1024 1025 1026 1027 1028 1029 1030 1031 1032 其中 0 出…...

如何解决git clone http/https仓库失败(403错误)

本来不打算写这篇文章,但是后来又遇到这个问题忘了之前是怎么解决的了。 一般情况下,个人使用 GitHub 等平台时是使用 SSH 协议的,这样不光方便管理可访问用户,也保证了安全性。但是 GitHub 上仓库的 SSH 地址是要登陆才能看到&a…...

华为云云耀云服务器L实例评测 | 实例评测使用之硬件性能评测:华为云云耀云服务器下的硬件运行评测

华为云云耀云服务器L实例评测 | 实例评测使用之硬件性能评测:华为云云耀云服务器下的硬件运行评测 介绍华为云云耀云服务器 华为云云耀云服务器 (目前已经全新升级为 华为云云耀云服务器L实例) 华为云云耀云服务器是什么华为云云耀…...

Elasticsearch:使用 Elasticsearch 进行语义搜索

在数字时代,搜索引擎在通过浏览互联网上的大量可用信息来检索数据方面发挥着重要作用。 此方法涉及用户在搜索栏中输入特定术语或短语,期望搜索引擎返回与这些确切关键字匹配的结果。 虽然关键字搜索对于简化信息检索非常有价值,但它也有其局…...

JVM的主要组成及其作用

jvm主要组成部分有: 类加载器、运行时数据区 (内存结构)、执行引擎、本地接口库、垃圾回收机制 Java程序运行的时候,首先会通过类加载器把Java 代码转换成字节码。然后运行时数据区再将字节码加载到内存中,但字节码文件只是JVM 的一套指令集规范&#xf…...

会议AISTATS(Artificial Intelligence and Statistics) Latex模板参考文献引用问题

前言 在看AISTATS2024模板的时候,发现模板里面根本没有教怎么引用,要被气死了。 如下,引用(Cheesman, 1985)的时候,模板是自己手打上去的?而且模板提供的那三个引用,根本也没有Cheesman这个人&#xff0c…...

2023最新外贸建站:WordPress搭建外贸独立站零基础小白保姆级教程

想从零开始建立一个外贸自建站,那么你来对地方了。 如果你还在找外贸建站或者是WordPress建站教程,不妨看看这篇文章,本教程涵盖了2023最新的外贸建站教程,你将学会使用WordPress自建外贸独立站,步骤包括购买域名主机…...

HTTP请求交互基础(基于GPT3.5,持续更新)

HTTP交互基础 目的HTTP定义详解HTTP协议(规范)1. 主要组成部分1.1 请求行(Request Line):包含请求方法、请求URI(Uniform Resource Identifier)和HTTP协议版本。1.2 请求头部(Reques…...

小谈设计模式(6)—依赖倒转原则

小谈设计模式(6)—依赖倒转原则 专栏介绍专栏地址专栏介绍 依赖倒转原则核心思想关键点分析abc 优缺点分析优点降低模块间的耦合度提高代码的可扩展性便于进行单元测试 缺点增加代码的复杂性需要额外的设计和开发工作 Java代码实现示例分析 总结 专栏介绍…...

JetBrains常用插件

Codota AI Autocomplete Java and JavaScript:自动补全插件 Background Image plus:背景图片设置 rainbow brackets:彩虹括号,便于识别 CodeGlance2: 类似于 Sublime 中的代码缩略图(代码小地图&#xff…...

【C++哈希应用】位图、布隆过滤器

【C哈希应用】位图、布隆过滤器 目录 【C哈希应用】位图、布隆过滤器位图概念位图的实现位图改造位图应用总结布隆过滤器布隆过滤器的提出布隆过滤器的概念布隆过滤器的查找布隆过滤器删除布隆过滤器优点布隆过滤器缺陷 作者:爱写代码的刚子 时间:2023.9…...

Qt 编译纯c的C99的项目, error: undefined reference to `f()‘

把Cpp的后缀该为C是什么样的 尝试引用一个奇门排盘的c程序,在git上找到的叫cqm, 然后总是报错 error: undefined reference to f() 很是郁闷 于是新建了个项目试验一下,终于摸清了需要命名空间。 后来这么写就可以了 a.h namespace XX …...

TensorFlow入门(五、指定GPU运算)

一般情况下,下载的TensorFlow版本如果是GPU版本,在运行过程中TensorFlow能自动检测。如果检测到GPU,TensorFlow会默认利用找到的第一个GPU来执行操作。如果机器上有超过一个可用的GPU,除第一个之外的其他GPU默认是不参与计算的。如果想让TensorFlow使用这些GPU执行操作,需要将运…...

Unity - 实践: Metallic流程贴图 转 Specular流程贴图

文章目录 目的Metallic Flow - SP - 输出输出的 MRA (MGA) 贴图 Metallic->Specular (根据教程一步一步实践)1. Base color Metallic -> Diffuse2. Base color Metallic -> Specular3. Roughness -> Glossiness输出贴图,在 unity 中展示:M…...

第三章:最新版零基础学习 PYTHON 教程(第四节 - Python 运算符—Python 逻辑运算符及示例)

运算符用于对值和变量执行操作。这些是执行算术和逻辑计算的特殊符号。运算符运算的值称为操作数。 表中的内容逻辑运算符 逻辑与运算符 逻辑或运算符 逻辑非运算符 逻辑运算符的求值顺序 逻辑运算符 在 Python 中,逻辑运算符用于条件语句(True 或 False)。它们执行逻辑 AN…...

如何做好测试?(三)功能测试 (Functional Testing, FT)

1. 功能测试的详细介绍: 功能测试 (Functional Testing, FT),是一种软件测试方法,旨在验证系统的功能是否按照需求规格说明书或用户期望的方式正常工作。它关注系统的整体行为,以确保各个功能模块和组件之间的交互和集成正确。 …...

Ubuntu-Server-22.04安装桌面+VNC

前提:Ubuntu Server安装好后,ubantu其他版本是否适用这里未知,欢迎大佬们前来评论 一、默认没有图形界面,有时觉得用图形界面操作更简单直接,于是用如下命令安装: 1.更新本地环境 sudo apt-get update s…...

职业规划,什么是职业兴趣 - 我喜欢做什么?

能够在工作岗位上面做出成绩的人,都是结合自身兴趣,对职业进行合理规划的那一类。尤其是步入中年以后,能够创造出巨大价值的人,无一例外都是喜欢自己职业的人。没有将兴趣融入工作的人,只能够忍受默默无闻地活着&#…...

基于Java的高校学生党员发展流程管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...

【NLP的python库(03/4) 】: 全面概述

一、说明 Python 对自然语言处理库有丰富的支持。从文本处理、标记化文本并确定其引理开始,到句法分析、解析文本并分配句法角色,再到语义处理,例如识别命名实体、情感分析和文档分类,一切都由至少一个库提供。那么,你…...

面试理论篇三

关于异常机制篇 异常描述 目录 关于异常机制篇异常描述 注:自用 1,Java中的异常分为哪几类?各自的特点是什么? Java中的异常 可以分为 可查异常(Checked Exception)、运行时异常(Runtime Exception) 和 错误(Error)三类。可查异…...

山西住房和城乡建设厅网站/河南seo和网络推广

以下有三个问题: 1、那些内存需要回收? java堆中创建的对象需要回收,以及方法区中的类需要卸载以及常量池需要回收。 2、什么时候回收? JVM通过可达性算法分析,如果一个对象到GC roots对象之间没有链,则该对象就会…...

做恋爱方面的网站/seo搜索优化待遇

中国矿业大学教职工代表大会第一次会议暨工会会员中国矿业大学第八届教职工代表大会暨第十四届工会会员代表大会第一次会议代表团代表名单(以姓氏笔画为序)(共18个代表团593名代表,其中:正式代表368人、特邀代表 30人、列席代表 195 人)矿业工程学院、安…...

电子商务网站建设 ppt/刷网站排名软件

在头文件<cmath>中包含有大量的数学计算函数&#xff0c;今天碰巧用到反正切函数atan和atan2计算斜率&#xff0c;简单说一下这两个函数用法上的一点区别&#xff1a; float angleatan(y/x); float angleatan2(y,x); 两点区别&#xff1a; 1.参数的填写方式不同 2.当…...

如何对现有的网站改版/内容营销

本文来自老男孩老师第三本书籍著作《老男孩的MySQL私房菜》第三章内容分享&#xff01;3.1 MySQL数据库的安装方法及选择在当今的互联网企业里&#xff0c;MySQL数据库大多运行在Linux系列操作系统上&#xff0c;当然&#xff0c;你也可以运行在Windows/Unix等商业操作系统上&a…...

lib wordpress/全网营销网络推广

现在验证码的种类真的是越来越多&#xff0c;短信验证码、语音验证码、图片验证码、滑块验证码 ... 我们在 PC 的网页端或者手机上的 app 进行登录或者注册时&#xff0c;应该总会遇见图片验证码&#xff0c;比如下面这类&#xff1a;上面这些图片验证码都是通过Python制作出来…...

做高端品牌网站/高端网站建设企业

1、引言 HitTest是命中测试的意思。在使用MFC编程的时候&#xff0c;在列表视图中通常会涉及到需要获取鼠标当前位置所对应的元素。这种通过光标位置来获得相应元素项的操作我们称之为命中测试。 2、获取光标位置 网上有人这样处理&#xff1a; DWORDdwPos ::GetMessagePos(…...