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 三种色彩空间的对比,涵盖了它们的定义、特点、应用场景和优缺点: 1. 定义 GRAY: 灰度图像仅包含亮度信息,每个像素用一个值(通常在0到255之间)表示亮度(黑到白&#x…...
丢垃圾视频时间检测 -- 基于状态机的实现
文章目录 OverviewKey PointsPseudo-code Overview 需要考虑的方面 状态定义和转换条件时序约束空间约束异常处理 状态机的设计需要考虑的场景: 没有人人进入人携带垃圾人离开但垃圾留下垃圾消失异常情况(检测失败、多人多垃圾等) Key P…...
【QT】一个简单的串口通信小工具(QSerialPort实现)
目录 0.简介 1.展示结果 1)UI界面: 2)SSCOM(模拟下位机收发): 3)VSPD虚拟串口驱动(连接上位机和下位机的串口): 4)实际收发消息效果及视频演…...
24/12/5 算法笔记<强化学习> doubleDQN,duelingDQN
我们前面了解了DQN网络的一些知识,然而DQN还有一些改进的方法,比如doubleDQN和duelingDQN,我们先来将一下doubleDQN和DQN. 先来对比一下 单一网络 vs. 双重网络 DQN:是一个深度神经网络来估计每个动作的Q值 DDQN:使用两个独立的深度神经网络…...
道可云人工智能元宇宙每日资讯|全国工商联人工智能委员会成立会议在南京举办
道可云元宇宙每日简报(2024年12月5日)讯,今日元宇宙新鲜事有: 全国工商联人工智能委员会成立会议在南京举办 全国工商联人工智能委员会成立会议日前在江苏省南京市举办。中央统战部副部长、全国工商联党组书记沈莹出席会议并讲话…...
MySQL数据库(2)-检查安装与密码重置
1. 数据库下载安装 下载地址:MySQL :: Download MySQL Community Server 2. My.ini配置文件 my.ini 文件通常在MySQL安装过程中自动创建, 并且可以根据需要进行编辑以调整服务器的行为。 3. 配置环境变量 4. 查询版本号 查询版本号:mysql…...
C# 13 中的新增功能
C# 12 中的新增功能C# 11 中的新增功能C# 10 中的新增功能C# 9.0 中的新增功能C# 8.0 中的新增功能C#7.0中有哪些新特性?C#6.0中10大新特性的应用和总结C# 5.0五大新特性 将C#语言版本升级为预览版 C# 13 包括一些新增功能。 可以使用最新的 Visual Stu…...
视频自学笔记
一、视频技术基本框架 二、视频信号分类 2.1信号形式 2.1.1模拟视频 模拟视频是指由连续的模拟信号组成的视频图像,以前所接触的电影、电视都是模拟信号,之所以将它们称为模拟信号,是因为它们模拟了表示声音、图像信息的物理量。摄像机是获…...
easyexcel 导出日期格式化
1.旧版本 在新的版本中formate已经被打上废弃标记。那么不推荐使用这种方式。 2.推荐方式 推荐使用另外一种方式【 Converter 】代码如下,例如需要格式化到毫秒【yyyy-MM-dd HH:mm:ss SSS】级别 创建一个公共Converter import com.alibaba.excel.converters.Conv…...
02-开发环境搭建
02-开发环境搭建 鸿蒙开发环境的准备主要分为以下环节: 注册开发者实名认证创建应用下载安装开发工具新建工程 注册开发者 在华为开发者联盟网站上,注册成为开发者,并完成实名认证。 打开华为开发者联盟官网,点击“注册”进入…...
DBeaver导入csv到数据库
DBeaver的图标是一只小浣熊,查了下Beaver确实是浣熊的意思,看起来还是蛮可爱的。 业务上有需要导入csv到数据库的需求,试用了下,发现挺好用的。有很多属性可以定制。 导入步骤: 1.建表,表字段与待导入cs…...
React第十一节 组件之间通讯之发布订阅模式(自定义发布订阅器)
组件之间通讯常用方案 1、通过props 2、通过context 3、通过发布订阅模式 4、通过Redux 后面会有专栏介绍 什么情况下使用发布订阅模式 a、当我们想要兄弟组件之间通讯,而共同的父组件中又用不到这些数据时候; b、当多个毫无相关的组件之间想要进行数据…...
tcpreplay/tcpdump-重放网络流量/捕获、过滤和分析数据包
tcpdump 是一个网络数据包分析工具,通过捕获并显示网络接口上传输的数据包,帮助用户分析网络流量。 原理:用户态通过 libpcap 库控制数据包捕获,内核态通过网卡驱动获取数据包。 核心功能包括:捕获、过滤和分析数据包…...
ASPICE评估体系概览:对象、范围与参考标准解析
ASPICE(汽车软件过程改进和能力确定)是一个框架,它被广泛应用于汽车行业的软件开发和维护过程的改进。 它类似于软件工程领域的CMMI(能力成熟度模型集成),但专门针对汽车行业,考虑了该行业特有…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
