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

23种设计模式之装饰模式

目录

  • 1. 简介
  • 2. 代码
    • 2.1 ABatterCake (抽象组件)
    • 2.2 BatterCake (具体组件)
    • 2.3 ADecorator (抽象装饰者)
    • 2.4 EggDecorator (具体装饰者)
    • 2.5 SausageDecorator(具体装饰者)
    • 2.6 Test (测试)
    • 2.7 运行结果
  • 3. 优缺点
  • 4. 总结

1. 简介

装饰模式是一种结构型设计模式,它允许在运行时动态地给一个对象添加新的功能,同时又不改变其结构。这种模式通过创建一个装饰类,将原始对象包装起来,在装饰类中可以添加新的行为或者修改原始对象的行为。
装饰模式就像是给一个基础对象不断地 “穿上” 不同的功能 “外衣”,每一层 “外衣”(装饰类)都可以为对象添加一些额外的特性,而且这些 “外衣” 可以灵活地组合和叠加。

结构和角色

  • 抽象组件(Component):它是定义了被装饰对象的基本接口,既可以是一个抽象类,也可以是一个接口。这个接口声明了被装饰对象和装饰对象共有的方法,客户端代码可以通过这个接口来操作原始对象和装饰后的对象。
  • 具体组件(Concrete Component):它是抽象组件的具体实现类,实现了抽象组件中定义的接口,代表了被装饰的原始对象,提供了基本的功能。
  • 抽象装饰者(Abstract Decorator):它也实现了抽象组件接口,并且通常包含一个对抽象组件的引用。它的主要作用是为具体装饰者提供一个统一的接口,并且可以定义一些公共的装饰方法或者属性。
  • 具体装饰者(Concrete Decorator):它是抽象装饰者的具体实现类,用于给具体组件添加具体的功能。具体装饰者在实现抽象组件接口的方法时,会先调用所引用的抽象组件(原始对象)的方法,然后再添加自己的额外功能。

工作流程

  • 首先创建一个具体组件对象,这个对象提供了基本的功能。
  • 然后根据需要创建一个或多个具体装饰者对象,将具体组件对象传递给具体装饰者对象的构造函数,使得具体装饰者对象可以引用具体组件对象。
  • 当客户端调用具体装饰者对象的方法时,具体装饰者对象会先调用它所引用的具体组件对象的方法,然后再执行自己添加的额外功能。
  • 如果有多个具体装饰者对象,可以将一个具体装饰者对象包装在另一个具体装饰者对象中,形成多层装饰的效果,每次调用方法时,都会依次执行各层装饰者添加的功能和原始对象的功能。

2. 代码

2.1 ABatterCake (抽象组件)

public abstract class ABatterCake {protected abstract String getInfo();// 价格protected abstract int cost();
}

2.2 BatterCake (具体组件)

public class BatterCake extends ABatterCake{@Overrideprotected int cost() {return 5;}@Overrideprotected String getInfo() {return "煎饼";}
}

2.3 ADecorator (抽象装饰者)

public abstract class ADecorator extends ABatterCake{private ABatterCake aBatterCake;public ADecorator(ABatterCake aBatterCake) {this.aBatterCake = aBatterCake;}@Overrideprotected String getInfo() {return this.aBatterCake.getInfo();}@Overrideprotected int cost() {return this.aBatterCake.cost();}// 进行扩展protected abstract void doSomething();
}

2.4 EggDecorator (具体装饰者)

public class EggDecorator extends ADecorator{public EggDecorator(ABatterCake aBatterCake) {super(aBatterCake);}@Overrideprotected void doSomething() {}@Overrideprotected int cost() {return super.cost() + 2;}@Overrideprotected String getInfo() {return super.getInfo() + " 加一个鸡蛋";}
}

2.5 SausageDecorator(具体装饰者)

public class SausageDecorator extends ADecorator{public SausageDecorator(ABatterCake aBatterCake) {super(aBatterCake);}@Overrideprotected void doSomething() {}@Overrideprotected String getInfo() {return super.getInfo() + " 加一根香肠";}@Overrideprotected int cost() {return super.cost() + 2;}
}

2.6 Test (测试)


public class Test {public static void main(String[] args) {ABatterCake aBatterCake;aBatterCake = new BatterCake();aBatterCake = new EggDecorator(aBatterCake);aBatterCake = new SausageDecorator(aBatterCake);System.out.println("细节:" + aBatterCake.getInfo() + "\n价格: " + aBatterCake.cost());}
}

2.7 运行结果

细节:煎饼 加一个鸡蛋 加一根香肠
价格: 9

3. 优缺点

  • 优点
    • 灵活性高:可以在运行时动态地添加或删除对象的功能,通过组合不同的装饰者,可以创造出多种功能组合的对象,满足不同的需求。
    • 符合开闭原则:不需要修改原始类的代码就可以为其添加新的功能。当需要添加新的功能时,只需要创建新的装饰者类并实现相应的装饰逻辑即可。
    • 可维护性好:每个装饰者类只关注自己添加的功能,功能单一,代码结构清晰,便于理解和维护。
  • 缺点
    • 会增加系统的复杂性:随着装饰者的增多,系统中类的数量会增加,尤其是在多层装饰的情况下,代码的逻辑可能会变得复杂,理解和调试成本会增加。
    • 可能会导致设计过度灵活:过度使用装饰模式可能会使系统的设计变得过于复杂和难以控制,在一些简单的场景下可能会显得有些 “大材小用”。

4. 总结

相关文章:

23种设计模式之装饰模式

目录 1. 简介2. 代码2.1 ABatterCake (抽象组件)2.2 BatterCake (具体组件)2.3 ADecorator (抽象装饰者)2.4 EggDecorator (具体装饰者)2.5 SausageDecorator(具体装饰者…...

HTMLHTML5革命:构建现代网页的终极指南 - 2. HTMLHTML5H5的区别

HTML&HTML5革命:构建现代网页的终极指南 2. HTML&HTML5&H5的区别 大家好,我是莫离老师 在上一节课,我们了解了HTML的重要性和前端开发的核心概念。 今天,我们将深入探讨 HTML、HTML5 和 H5 的区别,并重点…...

Django之ORM表操作

ORM表操作 1.ORM单表操作 首先想操作表的增删改查,需要先导入这个表,以之前创建的UserInfo表为例,在app下的views.py中导入 from app import modelsdef query(request):new_obj models.UserInfo(id1,name北北,bday2019-09-27,checked1,)new_obj.save()return Htt…...

python下几个淘宝、天猫、京东爬虫实例

以下是使用Python编写的针对淘宝、天猫、京东详情页的爬虫实例。请注意,这些实例仅供参考,实际使用时可能需要根据网站结构的变化进行调整,并且需要遵守各平台的爬虫协议和法律法规。 淘宝详情页爬虫实例 环境准备: Python 3.xSe…...

级联树结构TreeSelect和上级反查

接口返回结构 前端展示格式 前端组件 <template><div ><el-scrollbar height"70vh"><el-tree :data"deptOptions" :props"{ label: label, children: children }" :expand-on-click-node"false":filter-node-me…...

gradle下载慢解决方案2024 /12 /1android studio (Windows环境)

gradle下载慢解决方案2024 /12 /1 默认环境配置好了,环境配置和程序安装请出门右转 打开软件,点击右上角设置,找到如下设置页 选择本地安装并制定好你已经安装好的 gradle 应用保存即可 全局插件环境配置(新版本可以直接在设置中添加了) 找对应位置添加国内源并把前面的内置源…...

Python+OpenCV系列:GRAY BGR HSV

以下是 GRAY、BGR 和 HSV 三种色彩空间的对比&#xff0c;涵盖了它们的定义、特点、应用场景和优缺点&#xff1a; 1. 定义 GRAY&#xff1a; 灰度图像仅包含亮度信息&#xff0c;每个像素用一个值&#xff08;通常在0到255之间&#xff09;表示亮度&#xff08;黑到白&#x…...

丢垃圾视频时间检测 -- 基于状态机的实现

文章目录 OverviewKey PointsPseudo-code Overview 需要考虑的方面 状态定义和转换条件时序约束空间约束异常处理 状态机的设计需要考虑的场景&#xff1a; 没有人人进入人携带垃圾人离开但垃圾留下垃圾消失异常情况&#xff08;检测失败、多人多垃圾等&#xff09; Key P…...

【QT】一个简单的串口通信小工具(QSerialPort实现)

目录 0.简介 1.展示结果 1&#xff09;UI界面&#xff1a; 2&#xff09;SSCOM&#xff08;模拟下位机收发&#xff09;&#xff1a; 3&#xff09;VSPD虚拟串口驱动&#xff08;连接上位机和下位机的串口&#xff09;&#xff1a; 4&#xff09;实际收发消息效果及视频演…...

24/12/5 算法笔记<强化学习> doubleDQN,duelingDQN

我们前面了解了DQN网络的一些知识&#xff0c;然而DQN还有一些改进的方法&#xff0c;比如doubleDQN和duelingDQN,我们先来将一下doubleDQN和DQN. 先来对比一下 单一网络 vs. 双重网络 DQN:是一个深度神经网络来估计每个动作的Q值 DDQN:使用两个独立的深度神经网络&#xf…...

道可云人工智能元宇宙每日资讯|全国工商联人工智能委员会成立会议在南京举办

道可云元宇宙每日简报&#xff08;2024年12月5日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 全国工商联人工智能委员会成立会议在南京举办 全国工商联人工智能委员会成立会议日前在江苏省南京市举办。中央统战部副部长、全国工商联党组书记沈莹出席会议并讲话…...

MySQL数据库(2)-检查安装与密码重置

1. 数据库下载安装 下载地址&#xff1a;MySQL :: Download MySQL Community Server 2. My.ini配置文件 my.ini 文件通常在MySQL安装过程中自动创建&#xff0c; 并且可以根据需要进行编辑以调整服务器的行为。 3. 配置环境变量 4. 查询版本号 查询版本号&#xff1a;mysql…...

C# 13 中的新增功能

C# 12 中的新增功能C# 11 中的新增功能C# 10 中的新增功能C# 9.0 中的新增功能C# 8.0 中的新增功能C&#xff03;7.0中有哪些新特性&#xff1f;C#6.0中10大新特性的应用和总结C# 5.0五大新特性 将C#语言版本升级为预览版 C# 13 包括一些新增功能。 可以使用最新的 Visual Stu…...

视频自学笔记

一、视频技术基本框架 二、视频信号分类 2.1信号形式 2.1.1模拟视频 模拟视频是指由连续的模拟信号组成的视频图像&#xff0c;以前所接触的电影、电视都是模拟信号&#xff0c;之所以将它们称为模拟信号&#xff0c;是因为它们模拟了表示声音、图像信息的物理量。摄像机是获…...

easyexcel 导出日期格式化

1.旧版本 在新的版本中formate已经被打上废弃标记。那么不推荐使用这种方式。 2.推荐方式 推荐使用另外一种方式【 Converter 】代码如下&#xff0c;例如需要格式化到毫秒【yyyy-MM-dd HH:mm:ss SSS】级别 创建一个公共Converter import com.alibaba.excel.converters.Conv…...

02-开发环境搭建

02-开发环境搭建 鸿蒙开发环境的准备主要分为以下环节&#xff1a; 注册开发者实名认证创建应用下载安装开发工具新建工程 注册开发者 在华为开发者联盟网站上&#xff0c;注册成为开发者&#xff0c;并完成实名认证。 打开华为开发者联盟官网&#xff0c;点击“注册”进入…...

DBeaver导入csv到数据库

DBeaver的图标是一只小浣熊&#xff0c;查了下Beaver确实是浣熊的意思&#xff0c;看起来还是蛮可爱的。 业务上有需要导入csv到数据库的需求&#xff0c;试用了下&#xff0c;发现挺好用的。有很多属性可以定制。 导入步骤&#xff1a; 1.建表&#xff0c;表字段与待导入cs…...

React第十一节 组件之间通讯之发布订阅模式(自定义发布订阅器)

组件之间通讯常用方案 1、通过props 2、通过context 3、通过发布订阅模式 4、通过Redux 后面会有专栏介绍 什么情况下使用发布订阅模式 a、当我们想要兄弟组件之间通讯&#xff0c;而共同的父组件中又用不到这些数据时候&#xff1b; b、当多个毫无相关的组件之间想要进行数据…...

tcpreplay/tcpdump-重放网络流量/捕获、过滤和分析数据包

tcpdump 是一个网络数据包分析工具&#xff0c;通过捕获并显示网络接口上传输的数据包&#xff0c;帮助用户分析网络流量。 原理&#xff1a;用户态通过 libpcap 库控制数据包捕获&#xff0c;内核态通过网卡驱动获取数据包。 核心功能包括&#xff1a;捕获、过滤和分析数据包…...

ASPICE评估体系概览:对象、范围与参考标准解析

ASPICE&#xff08;汽车软件过程改进和能力确定&#xff09;是一个框架&#xff0c;它被广泛应用于汽车行业的软件开发和维护过程的改进。 它类似于软件工程领域的CMMI&#xff08;能力成熟度模型集成&#xff09;&#xff0c;但专门针对汽车行业&#xff0c;考虑了该行业特有…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...