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

Java特性之设计模式【装饰器模式】

一、装饰器模式

概述

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装

装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为

主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀

何时使用:在不想增加很多子类的情况下扩展类

优缺点

优点:

  • 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能

缺点:

  • 多层装饰比较复杂

1. 各个角色介绍

1.1 抽象组件(Component)

  • 定义了组合中所有对象的通用接口,可以是抽象类或接口。它声明了用于访问和管理子组件的方法,包括添加、删除、获取子组件等

1.2 具体组件(Concrete Component)

  • 是被装饰的原始对象,它定义了需要添加新功能的对象

1.3 抽象装饰器(Decorator)

  • 继承自抽象组件,它包含了一个抽象组件对象,并定义了与抽象组件相同的接口,同时可以通过组合方式持有其他装饰器对象

1.4 具体装饰器(Concrete Decorator)

  • 实现了抽象装饰器的接口,负责向抽象组件添加新的功能。具体装饰器通常会在调用原始对象的方法之前或之后执行自己的操作

2. UML图

​ 将创建一个 Shape 接口和实现了 Shape 接口的实体类。然后创建一个实现了 Shape 接口的抽象装饰类 ShapeDecorator,并把 Shape 对象作为它的实例变量。RedShapeDecorator 是实现了 ShapeDecorator 的实体类

在这里插入图片描述

3. 具体例子和代码

角色分配

  • Shape:形状接口

    • Rectangle:实现形状接口的长方形类
    • Circle:实现形状接口的圆形类
  • ShapeDecorator:形状装饰器抽象类

    • RedShapeDecorator:红色形状装饰器(继承ShapeDecorator)

3.1 抽象组件及其实现类

  • Shape
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 形状接口* @since 2024/3/15 16:23*/
public interface Shape {/*** 形状绘制动作*/void draw();}
  • Rectangle
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 长方形* @since 2024/3/15 16:26*/
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Shape: Rectangle");}}
  • Circle
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 圆形* @since 2024/3/15 16:28*/
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Shape: Circle");}}

3.2 抽象装饰器及其具体装饰器

  • ShapeDecorator
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 形状装饰器* @since 2024/3/15 16:30*/
public abstract class ShapeDecorator implements Shape {protected Shape decoratedShape;public ShapeDecorator(Shape decoratedShape) {this.decoratedShape = decoratedShape;}public void draw() {decoratedShape.draw();}}
  • RedShapeDecorator
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 红色形状装饰器* @since 2024/3/15 16:32*/
public class RedShapeDecorator extends ShapeDecorator {public RedShapeDecorator(Shape decoratedShape) {super(decoratedShape);}@Overridepublic void draw() {decoratedShape.draw();setRedBorder(decoratedShape);}private void setRedBorder(Shape decoratedShape) {System.out.println("Border Color: Red");}}

3.3 测试主函数

package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 装饰器模式* @since 2024/3/15 16:39*/
public class Main {public static void main(String[] args) {Shape circle = new Circle();// ShapeDecorator redCircle = new RedShapeDecorator(new Circle());// ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());Shape redCircle = new RedShapeDecorator(new Circle());Shape redRectangle = new RedShapeDecorator(new Rectangle());System.out.println("Circle with normal border");circle.draw();System.out.println("\nCircle of red border");redCircle.draw();System.out.println("\nRectangle of red border");redRectangle.draw();}}
  • 测试结果

在这里插入图片描述

4. 使用场景

  • 动态增强功能:使用装饰器模式可在运行时为对象灵活地增加额外功能。通过组合各种装饰器,能够实现不同功能的组合,而无需改变原始对象的代码
  • 避免继承的功能扩展:当使用继承来增强对象功能时会导致类的层次结构过于复杂时,考虑采用装饰器模式。通过组合而非继承来实现功能扩展,避免了深层次和复杂的类继承结构
  • 维护对象的封装性:若需为对象添加功能,同时又不愿修改原始对象的代码或破坏其封装性,可采用装饰器模式。该模式不改变原对象结构,只是在其上方增添功能
  • 弹性组合多项功能:若需为对象添加多项功能,且这些功能可弹性组合,则可采用装饰器模式。透过组合各种装饰器,能够实现各种功能的组合,而无需创建大量子类
  • 贯彻单一职责原则:在需要将功能添加与原始对象实现分离,以符合单一职责原则时,可采用装饰器模式。每个装饰器类专注于一个特定功能,这有助于使类的职责更加明确

在这里插入图片描述

相关文章:

Java特性之设计模式【装饰器模式】

一、装饰器模式 概述 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装 装饰器模式通过将对象包装在装饰器类中,以…...

Leetcode算法题笔记(2)

目录 图论51. 岛屿数量解法一 52. 腐烂的橘子解法一 53. 课程表解法一 54. 实现 Trie (前缀树)解法一 回溯55. 全排列解法一 56. 子集解法一解法二 57. 电话号码的字母组合解法一 58. 组合总和解法一解法二 59. 括号生成解法一解法二 60. 单词搜索解法一 61. 分割回文串解法一 …...

二手车交易网站|基于JSP技术+ Mysql+Java+ B/S结构的二手车交易网站设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java,ssm,springboot的平台设计与实现项目系统开发资源(可…...

lora-scripts 训练IP形象

CodeWithGPU | 能复现才是好算法CodeWithGPU | GitHub AI算法复现社区,能复现才是好算法https://www.codewithgpu.com/i/Akegarasu/lora-scripts/lora-trainstable-diffusion打造自己的lora模型(使用lora-scripts)-CSDN博客文章浏览阅读1.1k次…...

Acwing 503. 借教室

Problem: 503. 借教室 文章目录 思路解题方法复杂度Code 思路 这是一个二分查找问题。我们需要找到最大的借教室数量,使得每个教室的借用时间不超过其可用时间。我们可以通过二分查找来找到这个最大的借教室数量。 解题方法 我们首先对所有的借教室请求按照结束时间…...

吴恩达深度学习笔记:浅层神经网络(Shallow neural networks)3.1-3.5

目录 第一门课:神经网络和深度学习 (Neural Networks and Deep Learning)第三周:浅层神经网络(Shallow neural networks)3.1 神经网络概述(Neural Network Overview)3.2 神经网络的表示(Neural Network Representation…...

Linux设备驱动开发 - 三色LED呼吸灯分析

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 展锐UIS7885呼吸灯介绍呼吸灯调试方法亮蓝灯亮红灯亮绿灯展锐UIS7885呼吸灯DTS配置ump9620 PMIC驱动ump9620中的LED呼吸灯驱动LED的tr…...

开发者的瑞士军刀:DevToys

DevToys: 一站式开发者工具箱,打造高效创意编程体验,让代码生活更加得心应手!—— 精选真开源,释放新价值。 概览 不知道大家是否在windows系统中使用过PowerToys?这是微软研发的一项免费实用的系统工具套…...

【vue3.0】实现导出的PDF文件内容是红头文件格式

效果图: 编写文件里面的主要内容 <main><div id"report-box"><p>线索描述</p><p class"label"><span>线索发现时间:</span> <span>{{ detailInfoVal?.problem.createdDate }}</span></p><…...

【CSP试题回顾】202012-2-期末预测之最佳阈值(优化)

CSP-202012-2-期末预测之最佳阈值 关键点 1.map的遍历方式 map<int, int>occ0Num, occ1Num; for (auto it thetaSet.begin(); it ! thetaSet.end(); it) {num num occ0Num[*it] - occ1Num[*it];auto nextIt next(it); // 获取下一个迭代器if (num > maxNum &a…...

docker学习笔记 三-----docker安装部署

我使用的部署环境是centos 7.9 1、安装依赖工具 yum install -y yum-utils device-mapper-persistent-data lvm2 安装完成如下图 2、添加docker的软件信息源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo url地址为如…...

FastAPI+React全栈开发02 什么是FARM技术栈

Chapter01 Web Development and the FARM Stack 02 What is the FARM stack and how does it fit together? FastAPIReact全栈开发02 什么是FARM技术栈 It is important to understand that stacks aren’t really special, they are just sets of technologies that cover…...

C#程序结构详解

目录 背景: 一、C#程序的基本组成部分 二、C# Hello World示例 三、程序结构解析 四、编译与执行C#程序 五、总结 背景: 在学习C#编程语言的过程中&#xff0c;了解程序的基本结构是非常重要的。C#程序由多个组成部分构成&#xff0c;每个部分都有其特定的功能和作用。下面…...

linux 清理空间

1. 根目录下执行命令&#xff0c;查看每个目录下文件大小总和 rootvm10-88-88-3 /]# du -h --max-depth1 79M ./tmp 123M ./etc 4.0K ./media 4.0K ./srv 104M ./boot 5.3G ./var 0 ./sys 8.6M ./dev 196G ./usr 4.0K ./mnt 285M ./opt…...

C语言:给结构体取别名的4种方法

0 前言 在进行嵌入式开发的过程中&#xff0c;我们经常会见到typedef这个关键字&#xff0c;这个关键字的作用是给现有的类型取别名&#xff0c;在实际使用过程中往往是将一个复杂的类型名取一个简单的名字&#xff0c;便于我们的使用。就像我们给很熟的人取外号一样&#xff…...

今天聊聊Docker

在数字化时代&#xff0c;软件应用的开发和部署变得越来越复杂。环境配置、依赖管理、版本控制等问题给开发者带来了不小的挑战。而Docker作为一种容器化技术&#xff0c;正以其独特的优势成为解决这些问题的利器。本文将介绍Docker的基本概念、优势以及应用场景&#xff0c;帮…...

【C语言】结构体

个人主页点这里~ 结构体 一、结构体类型的声明1、结构的声明2、结构体变量的创建和初始化3、声明时的特殊情况4、自引用 二、结构体内存对齐1、对齐规则2、存在内存对齐的原因3、修改默认对齐数 三、结构体传参四、结构体实现位段 一、结构体类型的声明 我们在指针终篇中提到过…...

Git基础(24):分支回退

文章目录 前言放弃已修改的内容分支回退到指定commit 前言 将分支回退到之前的某个版本 开发中&#xff0c;可能开发某个功能不需要了&#xff0c;或者想要回退到之前历史的某个commit&#xff0c; 放弃后来修改的内容。 放弃已修改的内容 如果未提交&#xff0c;直接使用 …...

复试专业前沿问题问答合集1

复试专业前沿问题问答合集1 人工智能基础知识问答 Q1: 什么是人工智能(AI)? A1: 人工智能(AI)是计算机科学的一个分支,它涉及创建能够执行通常需要人类智能的任务的机器和软件。这些任务包括学习(获取信息并根据信息对其进行规则化以达到结论)、推理(使用规则达到近…...

C++标准库中提供的用于处理正则表达式的类std::regex

std 是 C 标准库的命名空间&#xff0c;包含了大量标准的 C 类、函数和对象。这些类和函数提供了广泛的功能&#xff0c;包括输入输出、容器、算法、字符串处理等。 通常&#xff0c;为了使用标准库中的对象和函数&#xff0c;需在代码中包含相应的头文件&#xff0c;比如 #in…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

SpringAI实战:ChatModel智能对话全解

一、引言&#xff1a;Spring AI 与 Chat Model 的核心价值 &#x1f680; 在 Java 生态中集成大模型能力&#xff0c;Spring AI 提供了高效的解决方案 &#x1f916;。其中 Chat Model 作为核心交互组件&#xff0c;通过标准化接口简化了与大语言模型&#xff08;LLM&#xff0…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...