【设计模式-结构型】装饰器模式

devtools/2025/1/18 23:19:47/

一、什么是装饰器模式

        装饰器模式(Decorator Pattern)是一种结构型设计模式,它的核心思想是在不改变原有对象结构的情况下,动态地给对象增加一些功能,从而达到扩展功能的目的。举个例子,今天在家妈妈给蒸馒头。馒头蒸的过程中,妈妈去收拾衣服了。突然想起来,馒头好了,就跟你说:“帮我把馒头拿出来。”这个时候馒头特别烫,如果不烫其实用我们的手是可以拿出来的,但是这个时候光用手拿不行。所以我们想了个办法,找了一个手套,从而把馒头拿了出来。这个过程就类似于装饰器模式,手套相当于装饰器,给手(原有对象)增加了隔热的功能,使得手能够处理原本无法直接处理的烫馒头。

二、为什么使用装饰器模式

        基于上面的馒头场景,我们讨论一下为什么使用装饰器模式(为什么要戴手套):

  1. 动态扩展(撤销)功能:当需要在运行时为对象动态添加功能时,装饰器模式是一个很好的选择。例如,比如应对热馒头去拿的时候要隔热功能,不想隔热还可以直接上手。但是装饰的多了,手不热吗?手不累吗?所示要适当添加。别为了拿馒头装了一堆东西反而得不偿失。

  2. 避免子类爆炸:如果通过继承来扩展功能,可能会导致子类数量急剧增加,使得系统变得复杂且难以维护。装饰器模式可以避免这种情况,通过组合的方式动态添加功能(继承关系的替代)。

  3. 保持原有接口不变装饰器模式可以在不改变原有对象接口的情况下,增加新的功能,这使得客户端代码可以透明地使用被装饰的对象,而不需要修改客户端代码。(拿馒头的手,拿的功能不变

三、装饰器模式示例

  1. Component(抽象组件):定义了被装饰对象的接口,所有具体的组件和装饰器都实现这个接口。

    java">//我就是一个手,人们定义我叫手,收能拿东西
    public interface Hand {void pickUp(Object object) throws Exception;
    }
  2. ConcreteComponent(具体组件):实现了Component接口的具体组件,是被装饰的对象。

    java">//我是一个赤裸裸真是长在身上的手,人们说手可以拿东西,我也可以
    public class BareHand implements Hand {@Overridepublic void pickUp(Object object) throws Exception {if (object instanceof HotBun) {throw new Exception("我擦,太热了!");}System.out.println("Picked up " + object.getClass().getSimpleName() + " with bare hands.");}
    }
  3. Decorator(装饰器抽象类):也实现了Component接口,持有一个Component对象的引用,通过组合的方式动态地为Component对象添加新的功能。

    java">//其实手上没准可以加点东西 
    public abstract class HandDecorator implements Hand {protected Hand hand;public HandDecorator(Hand hand) {this.hand = hand;}@Overridepublic void pickUp(Object object) throws Exception {hand.pickUp(object);}
    }
  4. ConcreteDecorator(具体装饰器):实现了Decorator的具体装饰器,负责给Component对象添加具体的装饰功能。

    java">//我是手套
    public class GloveDecorator extends HandDecorator {public GloveDecorator(Hand hand) {super(hand);}@Overridepublic void pickUp(Object object) throws Exception {System.out.println("戴上手套去拿 " + object.getClass().getSimpleName());hand.pickUp(object);}
    }
  5. 客户端

    java">//我是一个热馒头
    public class HotBun {// 烫馒头的具体实现
    }
    java">public class Main {public static void main(String[] args) {Hand bareHand = new BareHand();try {bareHand.pickUp(new HotBun());} catch (Exception e) {System.out.println(e.getMessage());}// 使用手套装饰手Hand glovedHand = new GloveDecorator(bareHand);try {glovedHand.pickUp(new HotBun());} catch (Exception e) {System.out.println(e.getMessage());}}
    }//输出
    我擦,太热了!
    戴上手套去拿热馒头
    我擦,太热了!

http://www.ppmy.cn/devtools/151689.html

相关文章

Oracle 23ai新特性:使用列别名的 GROUP BY 和 HAVING 子句

摘要 随着数据库技术的不断发展,SQL 语言也在不断进化,以更好地满足数据查询和分析的需求。本文将探讨如何在 SQL 查询中使用列别名(column alias)或列位置(column position)来简化 GROUP BY 和 HAVING 子…

ios文件管理,沙盒机制以及如何操作“文件”APP,把文件共享到文件app

首先,系统是一个整体,那每个app是相互独立的,系统为每个app分配了一定的存储空间,也就是我们说的沙盒,每个app有自己独立的沙盒,文件存储在沙盒中,正常情况下app相互之间数据是不可以共享以及访…

优化神马关键词排名原理(优化神马搜索引擎关键词排名规则)

优化神马(即百度)关键词排名的原理主要基于搜索引擎的算法和用户体验的考量。以下是一些关键的优化原理: 一、搜索引擎算法 网页重要性评估: 搜索引擎通过复杂的算法评估网页的重要性和权威性,如基于PageRank的评估方…

ROS进阶:使用URDF和Xacro构建差速轮式机器人模型

前言 本篇文章介绍的是ROS高效进阶内容,使用URDF 语言(xml格式)做一个差速轮式机器人模型,并使用URDF的增强版xacro,对机器人模型文件进行二次优化。 差速轮式机器人:两轮差速底盘由两个动力轮位于底盘左…

【深度学习量化交易14】正式开源!看海量化交易系统——基于miniQMT的量化交易软件

我是Mr.看海,我在尝试用信号处理的知识积累和思考方式做量化交易,应用深度学习和AI实现股票自动交易,目的是实现财务自由~ 目前我正在开发基于miniQMT的量化交易系统——看海量化交易系统。 前13篇文章,我介绍了我开发的量化交易系…

异步任务与定时任务

一、异步任务 基于TaskExecutionAutoConfiguration配置类中,注册的ThreadPoolTaskExecutor线程池对象进行异步任务执行。 (一)手动执行异步任务 在yml中配置线程池参数 spring: task:execution:pool:core-size: 5 # 核心线程数max-size: 20 # 最大线…

网络安全 | 什么是正向代理和反向代理?

关注:CodingTechWork 引言 在现代网络架构中,代理服务器扮演着重要的角色。它们在客户端和服务器之间充当中介,帮助管理、保护和优化数据流。根据代理的工作方向和用途,代理服务器可分为正向代理和反向代理。本文将深入探讨这两种…

Elasticsearch Python 客户端是否与自由线程 Python 兼容?

作者:来自 Elastic Quentin_Pradet 在这篇文章中,我们将进行一些实验,看看 Python Elasticsearch 客户端是否与新的 Python 3.13 自由线程(free-threading)版本兼容,其中 GIL 已被删除。 介绍 但首先&…