23种设计模式-装饰器(Decorator)设计模式

装饰器设计模式

  • 🚩什么是装饰器设计模式?
  • 🚩装饰器设计模式的特点
  • 🚩装饰器设计模式的结构
  • 🚩装饰器设计模式的优缺点
  • 🚩装饰器设计模式的Java实现
  • 🚩代码总结
  • 🚩总结

🚩什么是装饰器设计模式?

装饰器设计模式(Decorator Pattern) 是一种 结构型设计模式,它允许你通过将对象放入 特殊封装对象 中来为原对象 动态添加新的行为。装饰器模式的核心思想是 在不改变原对象结构的情况下,扩展其功能

使用场景

  • 当需要 动态地添加或撤销对象的功能 时。

  • 继承不适合扩展功能 时(例如,子类数量爆炸或功能组合复杂)。

  • 当需要 为对象添加多个独立的功能,且这些功能可以自由组合时。

🚩装饰器设计模式的特点

  • 动态扩展:装饰器模式允许在运行时动态地为对象添加功能。

  • 灵活性:可以自由组合多个装饰器,实现功能的叠加。

  • 避免继承:通过组合替代继承,避免子类数量爆炸。

  • 透明性:装饰器对象与原对象具有相同的接口,客户端无需知道是否被装饰。

🚩装饰器设计模式的结构

装饰器模式主要包含以下部分:

  • Component(抽象组件):定义对象的接口,可以是抽象类或接口。

  • ConcreteComponent(具体组件):实现 Component 接口,是被装饰的原始对象。

  • Decorator(抽象装饰器):继承或实现 Component,并持有一个 Component 对象的引用。

  • ConcreteDecorator(具体装饰器):实现 Decorator,为 Component 添加新的行为。

图例:

在这里插入图片描述

🚩装饰器设计模式的优缺点

✅ 优点

  • 动态扩展:可以在运行时动态地为对象添加功能。

  • 灵活性:可以自由组合多个装饰器,实现功能的叠加。

  • 避免继承:通过组合替代继承,避免子类数量爆炸。

  • 透明性:装饰器对象与原对象具有相同的接口,客户端无需知道是否被装饰。

❌ 缺点

  • 复杂性:装饰器模式会增加系统的复杂性,尤其是在多层装饰时。

  • 调试困难:由于装饰器是动态添加的,调试时可能难以追踪具体的装饰逻辑。

🚩装饰器设计模式的Java实现

代码地址:GitHub

  • 创建 抽象组件 Person,定义对象的接口。
/*** @author hanson.huang* @version V1.0* @ClassName Person* @Description 抽象组件 Person* @date 2025/3/24 15:35**/
public abstract class Person {protected String name;public abstract void Operation();// 职责
}
  • 创建 具体组件 Student,实现 Person 接口。
/*** @author hanson.huang* @version V1.0* @ClassName Student* @Description 具体组件* @date 2025/3/24 15:41**/
public class Student extends Person {public Student(String name) {this.name = name;}@Overridepublic void Operation() {System.out.println(name + "的职责:学习 ");}
}
  • 创建 抽象装饰器 Decorator,继承 Person 并持有一个 Person 对象的引用
/*** @author hanson.huang* @version V1.0* @ClassName Decorator* @Description 抽象装饰器* @date 2025/3/24 15:42**/
public abstract class Decorator extends Person {protected Person person;
}
  • 创建 具体装饰器 DecoratorADecoratorB,分别实现新的行为。

    • DecoratorA
    /*** @author hanson.huang* @version V1.0* @ClassName DecoratorA* @Description 具体装饰器 DecoratorA* @date 2025/3/24 15:42**/
    public class DecoratorA extends Decorator {public DecoratorA(Person person) {this.person = person;}@Overridepublic void Operation() {// 职责person.Operation();// 原本的职责System.out.print("写作业 ");}
    }
    
    • DecoratorB
    /*** @author hanson.huang* @version V1.0* @ClassName DecoratorB* @Description 具体装饰器 DecoratorB* @date 2025/3/24 15:45**/
    public class DecoratorB extends Decorator {public DecoratorB(Person person) {this.person = person;}@Overridepublic void Operation() {// 职责person.Operation(); // 原本的职责System.out.print("考试 ");}
    }
    
  • 测试装饰器模式

/*** @author hanson.huang* @version V1.0* @ClassName DecoratorPattern* @Description 测试装饰器模式* @date 2025/3/24 15:46**/
public class DecoratorPattern {public static void main(String[] args) {Person zhangsan = new Student("张三");zhangsan= new DecoratorA(zhangsan);zhangsan= new DecoratorB(zhangsan);zhangsan.Operation();System.out.println("\n=====我是分割线=====");// 对象链Person lisi = new DecoratorB(new DecoratorA(new Student("李四")));lisi.Operation();}
}

📌 运行结果

在这里插入图片描述

🚩代码总结

  • 抽象组件 Person 定义对象的接口。

  • 具体组件 Student 实现 Person 接口,是被装饰的原始对象。

  • 抽象装饰器 Decorator 继承 Person 并持有一个 Person 对象的引用

  • 具体装饰器 DecoratorA 和 DecoratorB 分别实现新的行为。

  • 客户端 通过组合装饰器动态扩展对象的功能。

🚩总结

  • 装饰器设计模式(Decorator Pattern) 允许你通过将对象放入 特殊封装对象 中来为原对象 动态添加新的行为

  • 适用于 动态扩展对象功能避免继承导致的子类数量爆炸自由组合多个功能 的场景。

  • Java 实现 需要 定义抽象组件具体组件抽象装饰器具体装饰器,并通过组合方式动态扩展功能。

✅ 适用场景:

  • 需要 动态地添加或撤销对象的功能 时。

  • 继承不适合扩展功能 时。

  • 需要 为对象添加多个独立的功能,且这些功能可以自由组合时

  • Java中许多地方用到了装饰器模式,例如,I/O流中的InputStream就是抽象的基础组件,而,BufferedInputStreamDataInputStream 属于是装饰器类。Java的Collections 集合类Collections.synchronizedList 方法返回的列表是装饰后的组件,它具备了线程安全的特性

在这里插入图片描述

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

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

相关文章

[Vue]事件修饰符

文章目录 一、语法介绍二、添加代码三、结果展示四、参考文献 如有错误,请指正!!! 一、语法介绍 1、问题来源 我们在处理网页时,当点击按钮时会触发对应事件,但是有时并不想触发该时间&#xff0c…

Go 语言 sync 包使用教程

Go 语言 sync 包使用教程 Go 语言的 sync 包提供了基本的同步原语,用于在并发编程中协调 goroutine 之间的操作。 1. 互斥锁 (Mutex) 互斥锁用于保护共享资源,确保同一时间只有一个 goroutine 可以访问。 特点: 最基本的同步原语&#x…

ubuntu22.04安装搜狗输入法保姆教程~

一、添加中文语言支持 1.首先打开设置,找到Language and Region 2.点击Manage Installed Languages 3.点击 Install/Remove Languages... 4.选中Chinese (simplified),点击Apply

docker中间件部署

1.docker安装 # 1.卸载旧版本 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine# 2.需要的安装包 yum install -y yum-utils# 3.设置镜像的仓库 # 3.1.默认是国外的&#x…

python康复日记-request库的使用,爬虫自动化测试

一,request的简单应用 #1请求地址 URLhttps://example.com/login #2参数表单 form_data {username: admin,password: secret } #3返回的响应对象response response requests.post(URL,dataform_data,timeout5 ) #4处理返回结果,这里直接打印返回网页的…

强化学习和智能决策:Q-Learning和Deep Q-Learning算法

强化学习(Reinforcement Learning, RL)是机器学习的一个重要分支,它通过智能体(Agent)与环境交互来学习最优决策策略,旨在最大化智能体的长期累积奖励。Q-Learning和Deep Q-Learning是强化学习中的两种关键算法,它们在智能决策领域发挥着重要作用。 一、强化学习基础 …

ubuntu22.04 安装Jitsi meet 开源会议系统,代替腾讯会议

0.安装 官方安装教程Self-Hosting Guide - Debian/Ubuntu server | Jitsi Meet 一定要用域名访问, 一定要用域名访问, 一定要用域名访问, 一定要用域名访问, 域名一定要有ssl证书,域名一定要有ssl证书,域名…

专家管理系统(源码+文档+讲解+演示)

引言 在知识经济时代,专家管理系统成为了企业优化知识资源、提升决策效率的重要工具。本文将介绍一款创新的专家管理系统,该系统通过智能化工具,助力企业实现专家资源的高效管理和利用。 平台概述 专家管理系统采用前后端分离的架构设计&a…

css基础-选择器

选择器进阶 子串选择器 /* 匹配 href 以 "https" 开头的链接 */ a[href^"https"] {color: green; }/* 匹配 href 包含 "example" 的链接 */ a[href*"example"] {text-decoration: underline; }/* 匹配 href 以 ".pdf" 结尾…

Spring Boot属性设置方法及优先级完整说明+表格对比

Spring Boot属性设置方法及优先级完整说明 官网参考: https://docs.spring.io/spring-boot/3.4-SNAPSHOT/reference/features/external-config.html#features.external-config.files 属性设置方法优先级顺序(从高到低) 命令行参数&#xf…

上门家政小程序实战,从0到1解决方案

一、逻辑分析 上门家政小程序主要涉及用户端和服务端两大部分。用户端需要实现服务浏览、预约下单、订单跟踪等功能;服务端则要处理订单管理、服务人员管理、数据统计等任务。以下是详细的功能模块分析: 用户注册与登录:用户通过手机号或第三…

LLVM学习-DragonEgg工具

2.2.2 使用DragonEgg和LLVM工具了解编译流程 如果希望看到前端的运行情况,请使用-S -fplugin-arg-dragonegg-emit-ir标志,该标志将产生以LLVM IR代码表示的人工可读文件。 一旦编译器将程序转换为IR则停止编译,并将内存中的表示内容写入磁盘的…

关于cmd中出现无法识别某某指令的问题

今天来解决以下这个比较常见的问题,安装各种软件都可能会发生,一般是安装时没勾选注册环境变量,导致cmd无法识别该指令。例如mysql,git等,一般初学者可能不太清楚。 解决这类问题最主要的是了解环境变量的概念&#x…

ThreadLocal详解与高频场景实战指南

ThreadLocal详解与高频场景实战指南 1. ThreadLocal概述 ThreadLocal是Java提供的线程本地变量机制,用于实现线程级别的数据隔离。每个访问该变量的线程都会获得独立的变量副本,适用于需要避免线程间共享数据的场景。 特点: 线程封闭性&a…

【C++初阶】---类和对象(上)

1.类的定义 1.1类的定义格式 • class为定义类的关键字,Data为类的名字,{}中为类的主体,注意类定义结束时后⾯分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的⽅法或者成员函数。 •…

Rust安装并配置配置vscode编译器

一. 下载rustup-init.exe rust下载网址:Getting started - Rust Programming Language 根据系统,选择适合的exe文件 我选择的的是右边64bit的 打开下载的文件 输入1,回车 二. Visual C 安装 自动下载安装vs 等待安装完毕 三. Rust 安装…

openGl片段着色器的含义

片段着色器的含义及代码中的应用说明: 1. 片段着色器的基本概念 片段着色器(Fragment Shader)是OpenGL着色器管线中的关键组件,主要用于计算屏幕空间中每个片段(对应像素)的最终颜色。它是图形渲染流程的…

事务的四大特性(ACID)详解

事务的四大特性(ACID)详解 在数据库管理系统(如 MySQL)中,事务(Transaction) 是指一组要么全部执行、要么全部不执行的数据库操作,通常用于确保数据的完整性和一致性。事务有四大核…

ubuntu设置开机自动运行应用

系统版本:Ubuntu 24.04.1 LTS桌面版 按招网上的资料显示,当前版本主要的实现方式有以下两种, 方式1:通过图形界面的【启动应用程序】设置开机自启动;方式2:配置为服务实现开机自启动。 但是在我的电脑上方…

ECharts各类炫酷图表/3D柱形图

一、前言 最近鸡米花实现了各类的炫酷的图表,有3D柱形图、双边柱形图以及异形柱形图,好了,直接上图: 二、效果图 一个个来吧,下面就是代码啦,注意,一下图表展示的宽高均为800px*300px 三、异形横…