23种设计模式之一— — — —装饰模式详细介绍与讲解

news/2024/9/25 15:20:04/

装饰模式详细讲解

  • 一、定义
  • 二、装饰模式结构
      • 核心思想
      • 模式角色
      • 模式的UML类图
      • 应用场景
      • 模式优点
      • 模式缺点
  • 实例演示
      • 图示
      • 代码演示
      • 运行结果

一、定义

装饰模式(别名:包装器)
装饰模式(Decorator Pattern)是结构型的设计模式,它允许在运行时动态地向对象添加新的职责或功能,同时保持对象的原始类不变。通过使用装饰器模式,可以在不修改现有代码的基础上扩展对象的功能,

二、装饰模式结构

核心思想

1.动态扩展:在不改变原类结构和继承关系的情况下,动态地为对象添加功能。
2.包装对象:通过创建一个包装对象(装饰器)来包裹真实对象,增加额外功能。
3.接口一致性:装饰器与真实对象有相同的接口,确保客户端能以相同的方式与两者交互。
4.开闭原则:对扩展开放,对修改关闭。新的功能通过添加装饰器实现,而不是修改原类。
5.灵活组合:允许通过组合多个装饰器来创建功能更为丰富的对象

模式角色

1.抽象组件(Component):定义一个接口,用于规范准备接收附加责任的对象(即被装饰对象)。
2.具体组件(ConcreteComponent):实现抽象组件接口,是装饰器要装饰的真实对象。
3.装饰器(Decorator):持有一个抽象组件的引用,并继承抽象组件的接口。它既可以使用所持有的引用调用被装饰的组件的方法,也可以增加新的功能。
4.具体装饰器(ConcreteDecorator):实现装饰器接口并给具体组件添加职责。它通常包含对具体组件的引用,以及一个或多个用于增加功能的额外方法。
这些角色在装饰模式中的交互方式是:

  • 抽象组件定义了所有装饰器对象和被装饰对象需要实现的接口。
  • 具体组件实现了抽象组件接口,是准备被装饰的对象。
  • 装饰器持有一个对抽象组件的引用,并且实现了抽象组件接口。它可以使用这个引用来调用被装饰对象的方法,并在调用前后添加新的功能。
  • 具体装饰器实现了装饰器接口,并且给具体组件添加新的职责。它通常包含一个指向被装饰对象的引用,以及用于实现附加功能的代码。

模式的UML类图

在这里插入图片描述

应用场景

  • 当需要为单个对象提供多种不同的行为或者表现形式时。
  • 需要向一个已经存在的类中添加功能,但又不希望修改该类的源代码或继承其子类时
  • 组合对象:当需要组合多个对象来创建一个具有更多功能的对象时,装饰模式是一个很好的选择。通过递归组合方式,可以构建出一个具有多种功能的对象。例如,在文件系统中,文件夹可以被视为一个特殊的文件,它可以包含其他文件和文件夹。使用装饰模式,可以将文件夹装饰为一个包含额外功能的对象,如支持加密、压缩等

模式优点

  • 动态地给对象添加功能,相比生成子类更加灵活、透明。
  • 无需修改原有类就可以扩展功能,符合开闭原则。
  • 装饰器可以被组合,以便在运行时动态地、多次地添加多个职责。

模式缺点

  • 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
  • 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
  • 不易调试:由于装饰器模式涉及到多个对象的交互,调试可能会变得相对困难。特别是当装饰器链很长时,追踪请求和响应的路径可能会变得复杂。

实例演示

图示

鸡腿堡应用:
在这里插入图片描述

代码演示

java">package ZhuangShiMoShi;public abstract class Humburger {protected String name;public String getName() {return name;}public abstract double getPrice();}package ZhuangShiMoShi;public class ChickenBurger extends Humburger {public ChickenBurger(){name="鸡腿堡";}public double getPrice(){return 10;}}package ZhuangShiMoShi;public abstract class Condiment extends Humburger {protected Humburger humburger;public abstract String getName();}package ZhuangShiMoShi;public class Chilli extends Condiment {public Humburger hum;public Chilli(Humburger hum) {this.hum = hum;}@Overridepublic String getName() {// TODO Auto-generated method stubreturn hum.getName() + " 加辣椒";}@Overridepublic double getPrice() {// TODO Auto-generated method stubreturn hum.getPrice();}}package ZhuangShiMoShi;public class Lettuce extends Condiment {public Humburger hum;public Lettuce(Humburger hum) {this.hum = hum;}@Overridepublic String getName() {// TODO Auto-generated method stubreturn hum.getName()+" 加生菜";}@Overridepublic double getPrice() {// TODO Auto-generated method stubreturn hum.getPrice()+1.5;}}

测试类:

java">package ZhuangShiMoShi;public class Test {public static void main(String[] args) {Humburger hum = new ChickenBurger();System.out.println(hum.getName() + " 价钱:" + hum.getPrice());Lettuce lettuce=new Lettuce(hum);System.out.println(lettuce.getName()+" 价钱:"+lettuce.getPrice());Chilli chilli1=new Chilli(hum);System.out.println(chilli1.getName()+" 价钱:"+chilli1.getPrice());Chilli chilli2=new Chilli(lettuce);System.out.println(chilli2.getName()+" 价钱:"+chilli2.getPrice());}}

运行结果

在这里插入图片描述

该代码主体是鸡腿堡,可以选择通过添加生菜、酱、辣椒等等许多其他的配料,并根据选择的配料计算相应的价格。
博主用心写,读者点关注;互动传真情,知识不迷路


http://www.ppmy.cn/news/1464475.html

相关文章

day22二叉树part08 | 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

**235. 二叉搜索树的最近公共祖先 ** 这里利用上了二叉搜索树的特性&#xff0c;从上到下遍历&#xff0c;最近的公共祖先一定是满足p->val < root->val < q->val的 class Solution { public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, Tr…

设计模式在芯片验证中的应用——单例

一、单例模式 单例模式(Singleton)是一种创建型设计模式&#xff0c;能够保证一个类只有一个实例&#xff0c; 并提供一个访问该实例的全局节点。验证环境配置(configuration)类、超时(timeout)处理类等可以使用单例实现。比如说验证环境需要在特定场景中监测特定接口上的超时事…

NSSCTF-Web题目4

[SWPUCTF 2021 新生赛]hardrce 1、题目 2、知识点 rce&#xff1a;远程代码执行、url取反编码 3、解题思路 打开题目 出现一段代码&#xff0c;审计源代码 题目需要我们通过get方式输入变量wllm的值 但是变量的值被过滤了&#xff0c;不能输入字母和\t、\n等值 所以我们需…

视频汇聚EasyCVR平台视图库GA/T 1400协议与GB/T 28181协议的区别

在公安和公共安全领域&#xff0c;视频图像信息的应用日益广泛&#xff0c;尤其是在监控、安防和应急指挥等方面。为了实现视频信息的有效传输、接收和处理&#xff0c;GA/T 1400和GB/T 28181这两个协议被广泛应用。虽然两者都服务于视频信息处理的目的&#xff0c;但它们在实际…

【Paddle】Inplace相关问题:反向传播、影响内存使用和性能

【Paddle】Inplace相关问题&#xff1a;反向传播、影响内存使用和性能 写在最前面inplace 的好处有哪些&#xff1f;能降低计算复杂度吗在反向传播时&#xff0c;Inplace为什么会阻碍呢&#xff1f;“计算图的完整性受损”表达有误原地操作 sin_()为什么原地操作会阻碍反向传播…

新人学习笔记之(数据)

一、数据类型简介 1.为什么需要数据类型 &#xff08;1&#xff09;在计算机中&#xff0c;不同的数据所需占用的储存空间数不同的&#xff0c;为了便于把数据分成所需内存大小不同的数据&#xff0c;充分利用储存空间&#xff0c;于是定义了不同的数据类型。 &#xff08;2&am…

基于xilinx FPGA的 FFT IP使用例程说明文档(可动态配置FFT点数,可计算信号频率与幅度)

目录 1 概述2 IP examples功能3 IP 使用例程3.1 IP设置3.2 fft_demo端口3.3 例程框图3.4 仿真结果3.5 仿真验证得出的结论4 注意事项5例程位置 1 概述 本文用于讲解xilinx IP 的FFT ip examples的功能说明&#xff0c;方便使用者快速上手。 参考文档&#xff1a;《PG109》 2 …

基于python flask的旅游数据大屏实现,有爬虫有数据库

背景 随着旅游行业的快速发展&#xff0c;数据在旅游决策和规划中的重要性日益凸显。基于 Python Flask 的旅游数据大屏实现研究旨在结合爬虫技术和数据库存储&#xff0c;为用户提供全面、实时的旅游信息展示平台。 爬虫技术作为数据采集的重要手段&#xff0c;能够从各种网…