实用指南:【结构型模式】装饰器模式

news/2025/10/8 15:56:40/文章来源:https://www.cnblogs.com/wzzkaifa/p/19129740

装饰器模式

装饰器模式(Decorator Pattern):动态地给一个对象增加一些额外的职责,对于“增加对象特性”而言,装饰器模式比生成子类实现更为灵活,且装饰器模式可以无限叠加。
在这里插入图片描述

装饰器模式当中的角色和职责

装饰器模式的标准类图如下:

画板

装饰器模式的代码实现

参考《Easy 搞定 Golang设计模式》,下面以“添加手机配件”为场景,实现一个使用装饰器模式的 Demo:

package main
import "fmt"
// --- --- --- 抽象层 --- --- ---
// 定义抽象的构件
type Phone interface {
Show(
) // 构件的功能
}
// 装饰器基础类, 本应该定义为 interface, 但由于 Golang 的 interface 只有方法没有成员, 所以定义为 struct
type Decorator struct {
phone Phone // 通过组合的方式实现 Decorator 基础类
}
func (d *Decorator) Show(
) {
}
// --- --- --- 实现层 --- --- ---
// 定义具体的构件
type Apple struct{
}
func (ap *Apple) Show(
) {
fmt.Println("正在使用苹果手机..."
)
}
type Realme struct{
}
func (rm *Realme) Show(
) {
fmt.Println("正在使用真我手机..."
)
}
// 定义具体的装饰器
type TiemoDecorator struct {
Decorator // 继承基础的装饰器类(主要继承 Phone 的成员属性)
}
func (td *TiemoDecorator) Show(
) {
td.phone.Show(
) // 调用被装饰构件的原方法
fmt.Println("贴膜的手机"
)
}
func NewTiemoDecorator(phone Phone) Phone {
return &TiemoDecorator{
Decorator{
phone
}
}
}
type ShoujikeDecorator struct {
Decorator
}
func (sd *ShoujikeDecorator) Show(
) {
sd.phone.Show(
)
fmt.Println("加装手机壳的手机"
)
}
func NewShoujikeDecorator(phone Phone) Phone {
return &ShoujikeDecorator{
Decorator{
phone
}
}
}
func main(
) {
var iphone Phone
iphone = new(Apple)
iphone.Show(
) // 调用原构件的方法
var tiemoIPhone Phone
tiemoIPhone = NewTiemoDecorator(iphone)
tiemoIPhone.Show(
)
var shoujikeIPhone Phone
shoujikeIPhone = NewShoujikeDecorator(iphone)
shoujikeIPhone.Show(
)
var tiemoAndShoujikeIPhone Phone
tiemoAndShoujikeIPhone = NewShoujikeDecorator(tiemoIPhone)
tiemoAndShoujikeIPhone.Show(
)
}

装饰器模式与代理模式有何不同?

通过装饰器模式相较于代理模式而言,其动态性更好一些。可以根据不同的场景选择不同的模式,比如对于逻辑上需要增加的场景,可以使用代理模式;而对于需要无状态平行增加功能的场景,则可以选用装饰器模式,因为装饰器模式能够进行无状态的迭代。

装饰器模式的优缺点

优点

  1. 对于扩展一个对象的能力,装饰器模式比继承更加灵活,不会导致类的个数急剧增加;
  2. 能够通过一种动态的方式来扩展一个对象的能力,从而实现不同的行为;
  3. 可以对一个对象进行多次装饰(无状态地平行添加功能);
  4. 具体的构件类与具体的装饰器类可以独立变化,用户可以根据必须新增具体构件类和具体装饰器类,原有代码无需改变,符合“开闭原则”。

缺点

  1. 使用装饰器模式进行系统设计时会产生很多小的对象,大量小对象的产生势必会占用更多的系统资源,影响程序性能;
  2. 装饰器模式比继承更加灵活,但同时也意味着相较于继承,装饰器模式更容易出错。对于多次装饰的对象,如果出现问题,调试时需要逐级排查,较为繁琐。

适用场景

  1. 通过动态、透明的方式为单个对象添加职责;
  2. 当不能采用继承的方式对系统进行扩展或采用继承不利于系统扩展与维护时,可以使用装饰器模式。

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

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

相关文章

美橙互联旗下网站东钱湖镇建设局网站

首先查看报错信息,这里提示我们78行有问题 这里是[[]] 这个内联表达式出了问题,在当前所在的script标签中加入th:inlinenone,然后重启项目,成功解决!

P10068 [CCO 2023] Line Town

考察符号的变化,如果是一正一负那么不会变,否则是两位一起奇偶翻转。把奇数位的符号翻转后,每个数可以认为是一个绝对值和符号的二元组。 对于序列最终的形态,其一定是一段负然后一些 \(0\) 再一段正,翻转后就是一…

AI元人文:共识锚定与智慧剪枝——构建人机共生认知经济体的完善理论体系与实践路径

AI元人文:共识锚定与智慧剪枝——构建人机共生认知经济体的完善理论体系与实践路径 在人工智能从“工具性辅助”迈向“社会性参与”的临界点,我们面临的已非单纯的技术瓶颈,而是文明层级的融合困境。其一为价值漂移…

网站页面优化工具沈阳网站关键词优化服务好

selenium无法识别非web的控件,上传文件窗口为系统自带,无法识别窗口元素。 上传文件有两种场景:input控制上传和非input控件上传。 大多数情况都是input控件上传文件,只有非常少数的使用自定义的非input上传文件。 一、input控…

羊蹄

羊蹄cf104679E:埃式筛法+前缀和 问题:对于节点为 1..N,若两个数有公共质因子(gcd(a, b) > 1)则在它们之间连一条无向边。问哪些点与 2 不连通? 数x与其最小质因子p连通(p ↔ x),当其与2不连通时,可以找到一中…

出题系统

又完善了一下,更好用了 代码如下: class Nums { public double GetTrue(){return True;} public double GetFalse() {return False;} public int GetCurrent() {return Current;} public int GetMAX() {return MAX;}…

io控制方式

程序直接控制方式 完成一次读写操作的流程(以读操作为例子) 1.cpu向控制器发出读指令,于是设备启动,并且状态寄存器设置为1(未就绪) 2.轮询检查控制器的状态 3.输入设备准备好数据后,将数据传给控制器,并且报告…

【基础】 - ACPI是什么?

【基础】 - ACPI是什么?ACPI(高级配置与电源接口)表格是固件与内核间的“硬件说明书”,包含设备拓扑、电源管理、中断路由等关键信息,直接影响内核对硬件的识别与控制。Linux内核通过解析ACPI表格实现硬件抽象,而…

我 是 人 机

花了两天时间把 Im Not A Robot 通关了,真有意思。 下面分享一下我的通关历程。 正解 Level 1 直接点即可。 Level 2 选择所有含有 STOP 标志的方块。 直接选即可。 Level 3 填字母。瞪两下就能看出来了。 Level 4 选…

28定律及其扩展衍生

28定律及其扩展推演 28定律这四个字是十分简洁凝练的,它及其衍生描述可以用来描述身边的大多数现象。 描述 28定律的描述: 1.我第一次接触28定律是在对社会经济描述上:“社会20%的人掌握全社会80%以上的财富。” 2.…

电脑怎么创建网站吗科技创新的重要前沿是

fastermaker-boot 是基于Spring Boot3 、Vue3 的一个代码简洁、结构清晰、开发高效、模块可扩展的单体项目的基础开发框架,包含代码生成器模块,适合初级开发者特别是大学生学习研究使用,也是中小型系统快速开发的利器。 开发技术: JDK 17、Sp…

广东省人防工程建设网站wordpress首页打开很慢

植物神经紊乱是一种内脏功能失调的综合征,是由于社压会力、工作压力、生活压力等等因素而导致的一种神经类疾病。长期患有这个疾病会给患者的生活、工作以及学习带来很严重的影响和危害。 有很多患有植物神经紊乱的患者,各种各样的症状的患者被所轻或重的…

3516cv610在sample_aiisp上多创一路编码流,方法 - 详解

3516cv610在sample_aiisp上多创一路编码流,方法 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&…

网站建设与维护技术浅谈论文代理加盟做什么好

http://cplusoj.com/d/senior/p/SS231025D 答案为 ∑ w [ x ] − w [ s o n [ x ] ] \sum w[x]-w[son[x]] ∑w[x]−w[son[x]], x x x 非儿子 要维护断边,LCT固然可以,但不一定需要 发现如果发生了变化,只会由重儿子变成次重儿子…

注册公司制作网站门户网站建设维护

LRU是什么意思 LRU是操作系统底层的一个页面置换算法,当空间不够需要换出最长时间没有使用的页面,在本题中的意思就是当到达容量上限的时候要换出最长时间没有被访问过的节点。 如何实现 LRU的实现可以使用链表的方式,参照MySQL的实现&…

手机模板网站模板下载工具网络网站建设推广

GODADDY的虚拟主机控制面板虽然使用起来非常方便,对于文件管理的很多操作也非常到位,但是有一个非常令人头疼的问题,就是GODADDY在 主机控制面板中只支持小于20M的文件打包,这对于大部分的站长朋友来说,是非常不方便的…

方法作业

https://files.cnblogs.com/files/blogs/847621/20243866牛蕴韬01方法作业.zip?t=1759908795&download=true

公司网站建设属于软件销售湖南金科建设有限公司网站

任何程序都可能出现错误,在SQL Server中执行Transact-SQL也不例外。如果在Transact-SQL中发生了错误,一般有两种捕捉错误的方法,一种是在客户端代码(如 c#、delphi等)中使用类似try...catch的语句进行捕捉;另外一种就是…

网站登录入口大全网站制作预算

作用:线程安全的全局静态变量初始化 声明: Q_GLOBAL_STATIC(MyType,globalState) Q_GLOBAL_STATIC_WITH_ARGS(MyType, globalState, (42, "Hello", "World")) //带参数的初始化 注: 构造函数和析构函数必须是公有的 如果…

实现仿中国婚博会微信小应用

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …