深入解析:【设计模式-3.5】结构型——装饰器模式

news/2025/10/6 10:34:19/文章来源:https://www.cnblogs.com/slgkaifa/p/19127365

深入解析:【设计模式-3.5】结构型——装饰器模式

说明:本文介绍结构型设计模式之一的装饰器模式

定义

装饰器模式(Decorator Pattern)也叫作包装器模式(Wrapper Pattern),指再不改变原有对象的基础上,动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活,属于结构型设计模式。(引自《设计模式就该这样学》P201)

化妆例子

以女孩化妆为例,如下:

(可展示接口,Showable)

/**
* 能展示的
*/
public
interface Showable {
/**
* 展示方法
*/
void show(
)
;
}

(女生对象,Girl)

/**
* 女生对象
*/
public
class Girl
implements Showable {
@Override
public
void show(
) {
System.out.print("女孩素颜的面容"
)
;
}
}

(装饰类,Decorator)

/**
* 装饰类
*/
public
class Decorator
implements Showable {
private Showable showable;
/**
* 构造器注入
*/
public Decorator(Showable showable) {
this.showable = showable;
}
@Override
public
void show(
) {
System.out.print("抹上淡淡的粉底【"
)
;
showable.show(
)
;
System.out.print("】"
)
;
}
}

(客户端,Client)

public
class Client {
public
static
void main(String[] args) {
new Decorator(
new Girl(
)
).show(
)
;
}
}

装饰器类扩展了原对象的功能,像是一种包装,包装后更丰富了

在这里插入图片描述

更进一步

在上述化妆的例子上,更进一步,抽象出一个装饰器类,如下:

(装饰抽象类,Decorator)

/**
* 装饰类
*/
public
abstract
class Decorator
implements Showable {
private Showable showable;
/**
* 构造器注入
*/
public Decorator(Showable showable) {
this.showable = showable;
}
@Override
public
void show(
) {
showable.show(
)
;
}
}

(粉底类,继承装饰类,FoundationMakeup)

/**
* 粉底类
*/
public
class FoundationMakeup
extends Decorator {
/**
* 构造器注入
*/
public FoundationMakeup(Showable showable) {
super(showable)
;
}
@Override
public
void show(
) {
System.out.print("抹上淡淡的粉底【"
)
;
super.show(
)
;
System.out.print("】"
)
;
}
}

(口红类,继承装饰类,Lipstick)

/**
* 口红类
*/
public
class Lipstick
extends Decorator {
/**
* 构造器注入
*/
public Lipstick(Showable showable) {
super(showable)
;
}
@Override
public
void show(
) {
System.out.print("抹上一层口红【"
)
;
super.show(
)
;
System.out.print("】"
)
;
}
}

(客户端使用,Client,可以自由组合装饰方式)

public
class Client {
public
static
void main(String[] args) {
// 搭配一
new Lipstick(
new FoundationMakeup(
new Girl(
)
)
).show(
)
;
System.out.println(
)
;
// 搭配二
new FoundationMakeup(
new Lipstick(
new Girl(
)
)
).show(
)
;
}
}

运行如下:

在这里插入图片描述

JDK源码体现

装饰器模式,在JDK的IO流设计上有体现,如下:

import java.io.BufferedInputStream
;
import java.io.File
;
import java.io.FileInputStream
;
import java.io.FileNotFoundException
;
import java.util.zip.ZipInputStream
;
public
class Client {
public
static
void main(String[] args)
throws FileNotFoundException {
// 装饰器模式在Java源码的体现
File file =
new File("./src/main/java/structural/decorator/Client.java"
)
;
ZipInputStream zipInputStream =
new ZipInputStream(
new BufferedInputStream(
new FileInputStream(file)
)
)
;
}
}

扒一下源码,可见ZipInputStreamBufferedInputStreamFileInputStream都继承自抽象类InputStream,类比一下前面的化妆例子,InputStream也就是装饰抽象类。

  • ZipInputStream -> InflaterInputStream -> FilterInputStream -> InputStream

  • BufferedInputStream -> FilterInputStream -> InputStream

  • FileInputStream -> InputStream

与代理模式的区别

关于装饰器模式与代理模式的区别,这里介绍两本书中给的区别:

代理模式和装饰模式在实现时有些类似,但是代理模式主要是给真是主题类增加一些全新的职责,例如权限控制、缓冲处理、智能引用、远程访问等,这些职责与原有职责不属于同一个问题域。而装饰模式是通过装饰类为具体构件类增加一些相关的职责,是对原有职责的扩展,这些职责属于同一问题域。代理模式和装饰模式的目的也不相同,前者是控制对对象的访问,而后者是为对象动态地增加功能。
(引自《设计模式的艺术》刘伟著,第一版P201)


在《设计模式就该这样学》(P214)中,举了一个不错的例子:

简单来讲,假设现在想租房,那么势必会有一些事务发生:房源搜索、联系房东谈价格等。

假设按照代理模式进行思考,那么小明只需要找到一个房产中介,让他去做房源搜索、联系房东谈价格这些事情,小明只需要等待通知然后付中介费就行了。

而如果采用装饰器模式进行思考,因为装饰器模式强调的是自身功能扩展,也就是说,如果要找房子,小明自身就要增加房源搜索能力扩展、联系房东谈价格能力扩展,通过相应的装饰器,提升自身能力,一个人做完所有的事情。

我的理解,装饰器模式与代理模式都能解决问题,没有非装饰器模式能解决的问题,代理模式也是,区别在于解决问题的角度:从内到外,是装饰器模式,从外到内,是代理模式。

总结

本文介绍了结构型设计模式中的装饰器模式,参考《设计模式就该这样学》、《秒懂设计模式》、《设计模式的艺术》三本书,其中化妆的例子来自《秒懂设计模式》。

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

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

相关文章

阿爸阿爸

10.6 口胡: QOJ833. Cells Blocking

Python 数据分析与可视化实战:从数据清洗到图表呈现 - 指南

Python 数据分析与可视化实战:从数据清洗到图表呈现 - 指南2025-10-06 10:29 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !importa…

深度学习优化器算法巧思速览

这一篇博文想写很久了,一直没有下笔,核心原因也是有一些待办的思路在攻关验证。 我们先从一个核心的问题出发, 1. 为什么要研究优化器算法? 它的关联问题:训练为什么要调参,调的是什么参? 如果就这个问题去问各…

完整教程:LangChain完全指南:从入门到精通,打造AI应用开发新范式

完整教程:LangChain完全指南:从入门到精通,打造AI应用开发新范式pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &quo…

在Windows下使用lucky实现TLS/SSL证书自动化

在Windows下使用lucky实现TLS/SSL证书自动化2024.06.06 TLS和SSL TLS 是传输层安全性协议 (Transport Layer Security) 的缩写 他的前身是 SSL 即安全套接层 (Secure Sockets Layer) 其目的是保障在互联网通信时数据…

NDK开发与实践(入门篇微课视频版)

本书旨在通过深入的理论与丰富的实战案例,引领读者系统学习NDK开发技术。NDK技术以其高安全性、卓越性能和高度复用性,成为现代应用开发的关键技术之一。本书从基本概念出发,全面介绍了NDK开发所需的核心基础知识,…

【深度学习优化算法】02:凸性 - 详解

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

温州通业建设工程有限公司网站深圳网站建站的公司

Git学习笔记 文章目录 Git学习笔记一、版本控制二、Linux基础命令三、Git的环境配置四、Git的基本理论(核心)五、Git项目的搭建六、Git文件操作七、使用码云八、IDEA集成git九、Git分支 一、版本控制 什么是版本控制 版本控制(Revision contr…

调了很久的代码总结

凡是在循环前面加了特判的东西,都要检查一下循环内部要不要判。 可以再读一遍题来调代码。

在Windows上搭建 EasyTier 公共服务器

在Windows上搭建 EasyTier 公共服务器2024.10.01 关于本教程 本教程将介绍如何在Windows上搭建 EasyTier 公共服务器 以帮助那些无公网的节点进行连接 值得注意的是EasyTier是不区分客户端和服务端的 其本身同时承载 服…

Transformer模型开发从0到1——原理深入与项目实践

本书分为5篇共17章。Transformer模型基础篇(第1~5章)重点介绍Transformer模型框架。把Transformer模型掰开,从最基础的输入出发,按照模型框架,一点一点走进Transformer模型的内部,直到最终的模型输出;Transform…

常州品牌网站建设免费文字变形logo设计

在软件工程中,设计模式是为了解决常见的软件设计问题而形成的一套经典解决方案。这些模式不仅能够帮助开发者提高设计的灵活性和代码的重用性,还能使问题的解决方案更加清晰、易于理解。《设计模式精解-GoF 23种设计模式》一书中所列举的23种…

毕业设计 网站开发简单吗蘑菇街网站模板

最近偶尔有用户反馈某些 HTTP 接口出现超时问题,而 web 服务端的 Trace 监控没有出现 http 返回值为 503 等异常情况。出现这种情况一般是web容器出现问题,客户端连 Arthas是Alibaba开源的Java诊断工具,深受开发者喜爱。 Github:h…

鸿蒙OS基于UniApp的区块链钱包创建实践:打造支持鸿蒙生态的Web3应用#三方框架 #Uniapp

鸿蒙OS&基于UniApp的区块链钱包创建实践:打造支持鸿蒙生态的Web3应用#三方框架 #Uniapppre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !impor…

CF700E

题目大意: 给定一个长为 \(n\) 的字符串 \(S\),你要找到最大的 \(k\),使得存在 \(s_{1} \sim s_{k}\) 使得 \(s_{1}\) 是 \(S\) 子串 且 \(s_{i}\) 在 \(s_{i - 1}\) 中作为子串至少出现两次。 \(n \le 2 \times 10…

价值弥漫:“AI元人文”的场域革命与共生之路

价值弥漫:“AI元人文”的场域革命与共生之路 本文探讨“价值弥漫”作为“AI元人文”核心实现路径的哲学基础与技术内涵,提出从“工具性AI”到“场域性AI”的范式转变。 引言:从“价值对齐”到“价值弥漫”的范式迁移…

手机app设计网站公司网站建设需要什么科目

流程图 一、前期准备 1.1 打开百度智能云官网找到管理中心创建应用 全选文字识别 1.2 保存好AppId、API Key和Secret Key 1.3 找到通用场景文字识别,立即使用 1.4 根据自己需要,选择要开通的项目 二、代码编写 以通用文字识别(高精度版&am…

k8s之pod概念

1. pod基本概念 2. pod网络概念 3. pod的生命周期和状态 4. 探针 5. 创建pod 6. 总结‍ 1. pod基本概念Kubernetes 中,Pod 是最小的网络调度单位, 每个pod可以放多个容器(例如可以放多个docke容器在同一个pod中运行…

鸿蒙版Taro 搭建开发环境 - 教程

鸿蒙版Taro 搭建开发环境 - 教程2025-10-06 10:09 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !import…

CF 1055 Div.1+Div.2

F - Triple Attack 我会了。 G - Query Jungle 我会了。 H1 - Victorious Coloring (Easy Version) 我不会。 H2 - Victorious Coloring (Hard Version) 我不会。