【设计模式】装饰器模式

2023-11-10

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

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

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。

介绍

意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

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

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

如何解决:将具体功能职责划分,同时继承装饰者模式。

关键代码: 1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。

应用实例: 1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。 2、不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

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

缺点:多层装饰比较复杂。

使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。

注意事项:可代替继承。

装饰器模式包含以下几个核心角色:

  • 抽象组件(Component):定义了原始对象和装饰器对象的公共接口或抽象类,可以是具体组件类的父类或接口。
  • 具体组件(Concrete Component):是被装饰的原始对象,它定义了需要添加新功能的对象。
  • 抽象装饰器(Decorator):继承自抽象组件,它包含了一个抽象组件对象,并定义了与抽象组件相同的接口,同时可以通过组合方式持有其他装饰器对象。
  • 具体装饰器(Concrete Decorator):实现了抽象装饰器的接口,负责向抽象组件添加新的功能。具体装饰器通常会在调用原始对象的方法之前或之后执行自己的操作。

装饰器模式通过嵌套包装多个装饰器对象,可以实现多层次的功能增强。每个具体装饰器类都可以选择性地增加新的功能,同时保持对象接口的一致性。

实现

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

RedShapeDecorator 是实现了 ShapeDecorator 的实体类。

DecoratorPatternDemo 类使用 RedShapeDecorator 来装饰 Shape 对象。

装饰器模式的 UML 图

步骤 1

创建一个接口:

Shape.java

public interface Shape {
   void draw();
}

步骤 2

创建实现接口的实体类。

Rectangle.java

public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Shape: Rectangle");
   }
}

Circle.java

public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Shape: Circle");
   }
}

步骤 3

创建实现了 Shape 接口的抽象装饰类。

ShapeDecorator.java

public abstract class ShapeDecorator implements Shape {
   protected Shape decoratedShape;
 
   public ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
   }
 
   public void draw(){
      decoratedShape.draw();
   }  
}

步骤 4

创建扩展了 ShapeDecorator 类的实体装饰类。

RedShapeDecorator.java

public class RedShapeDecorator extends ShapeDecorator {
 
   public RedShapeDecorator(Shape decoratedShape) {
      super(decoratedShape);     
   }
 
   @Override
   public void draw() {
      decoratedShape.draw();         
      setRedBorder(decoratedShape);
   }
 
   private void setRedBorder(Shape decoratedShape){
      System.out.println("Border Color: Red");
   }
}

步骤 5

使用 RedShapeDecorator 来装饰 Shape 对象。

DecoratorPatternDemo.java

public class DecoratorPatternDemo {
   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();
   }
}

步骤 6

执行程序,输出结果:

Circle with normal border
Shape: Circle

Circle of red border
Shape: Circle
Border Color: Red

Rectangle of red border
Shape: Rectangle
Border Color: Red

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【设计模式】装饰器模式 的相关文章

  • C++设计模式(8)——命令模式

    命令模式 亦称 动作 事务 Action Transaction Command 意图 命令模式是一种行为设计模式 它可将请求转换为一个包含与请求相关的所有信息的独立对象 该转换让你能根据不同的请求将方法参数化 延迟请求执行或将其放入队列中
  • 设计模式——Visitor(访问者)模式

    目录 前言 1 定义 2 适用性 3 结构 3 1 结构图 3 2 参与者 4 Java实际应用举例 以ASM技术为例 4 1 被访问对象 ClassReader 4 2 Visitor ClassVisitor 4 3 具体visitor
  • 设计模式-单一职责原则介绍与理解

    描述 一个类应该专注于实现一个功能 好处 便于代码复用 举例 俄罗斯方块游戏 首先可以想到的是游戏逻辑与界面的分离 也就是说逻辑一个类 界面部分一个类 这样做的好处就是我们可以复用游戏逻辑的代码 例如我们用java写了一个基于PC端的俄罗斯
  • 设计模式三: 代理模式(Proxy) -- JDK的实现方式

    简介 代理模式属于行为型模式的一种 控制对其他对象的访问 起到中介作用 代理模式核心角色 真实角色 代理角色 按实现方式不同分为静态代理和动态代理两种 意图 控制对其它对象的访问 类图 实现 JDK自带了Proxy的实现 下面我们先使用JD
  • 行为型模式-策略模式

    package per mjn pattern strategy 抽象策略类 public interface Strategy void show package per mjn pattern strategy 具体策略类 用来封装算法
  • 设计模式学习笔记(一)之单例模式

    单例模式 作用 保证一个类只有一个实例 并且提供访问这个实例的全局访问点 应用场景有 数据库连接池 spring中 Bean默认是单例 Servlet中 每一个Servlet是单例 配置文件的类 一般是单例 优点 单例只生成一个实例 减少系
  • 面向过程和面向对象的语言有哪些,以及优缺点(一篇文章让你理解)

    C语言是面向过程的 而C python java是面向对象的 面向过程的编程思想将一个功能分解为一 个一个小的步骤 我们通过完成一个一 个的小的步骤来完成一个程序 优点 这种编程方式 符合我们人类的思维 编写起来相对比较简单 缺点 但是这种
  • java需会(转载)

    一 基础篇 1 1 Java基础 面向对象的特征 继承 封装和多态 final finally finalize 的区别 Exception Error 运行时异常与一般异常有何异同 请写出5种常见到的runtime exception i
  • [C++]备忘录模式

    备忘录模式 Memento Pattern 保存一个对象的某个状态 以便在适当的时候恢复对象 备忘录模式属于行为型模式 github源码路径 https github com dangwei 90 Design Mode 此文件包含 mai
  • 设计模式学习之装饰器模式

    装饰器 Decorator 模式跟适配器 Adapter 模式一样 属于构建型设计模式 在学习适配器模式的时候说过 适配器模式的重点在复用能力 装饰器模式的重点在扩展能力 换言之 装饰器模式是先复用后扩展 这也导致了很多人跟适配器模式混淆
  • 设计模式 -- 工厂模式(Factory Pattern)

    简单工厂模式 Simple Factory Pattern 根据传入的参数决定实例化哪个对象 优点 不直接在客户端创建具体产品的实例 降低了耦合性 缺点 违反了开闭原则 对扩展开放 对修改关闭 不容易形成高内聚松耦合结构 每当我们增加一种产
  • 设计模式--Abstract server模式 VS Adapter 模式

    适配器类似于现实世界里面的插头 通过适配器 我们可以将分属于不同类的两种不同类型的数据整合起来 而不必去根据某一需要增加或者修改类里面的方法 Adapter mode和Proxymode的区别 Proxy的关注点是职能转移 通过引入Prox
  • 分享几个项目中用到的设计模式

    前言 之前项目中出于扩展性和有雅性的考虑 使用了多种设计模式进行项目框架的设计 主要的一些设计模式是单例模式 工厂模式 策略模式 责任链模式 代理模式这几种 现在依次讲讲这几个的主要是实现方式和在我们项目中的应用场景 核心设计模式分享 单例
  • [设计模式]模板方法模式(Template Method)

    1 意图 定义一个操作中的算法的骨架 而将一些步骤延迟到子类中 TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤 2 动机 其实就是如意图所描述的 算法的骨架是一样的 就是有些特殊步骤不一样 就可以
  • Java设计模式之装饰者设计模式Decorator Pattern

    目录 一 基本概念 二 结构 1 图示 三 案例演示 被装饰对象的基类 一个接口 有cost 和description 两个抽象方法 具体被装饰的对象 实现上面这个接口 装饰者抽象类 基类 实现drink接口 具体的装饰者类 糖 具体装饰者
  • 程序员必知的23种设计模式之组合模式

    文章目录 1 模式引出 学校院系展示需求 1 1 传统方案 1 2 传统方案问题分析 2 组合模式基本介绍 2 1 方案修改 3 组合模式解决的问题 4 组合模式的注意事项和细节 1 模式引出 学校院系展示需求 编写程序展示一个学校院系结构
  • 泛型与反射机制在JDBC和Servlet编程中的实践

    写在前面 泛型与反射是java中的两种强大机制 可以很好的提高代码的灵活性和复用性 本篇文章向大家展现在JDBC和Servlet编程场景下反射和泛型技术的实践 通过灵活使用这两种机制打造 高度可复用的JDBC和Servlet代码 1 JDB
  • 在AI技术的无情侵袭下,学学Java的23种设计模式还是非常有必要的

    目前国内80 程序员的主要工作是调用组合api实现各种业务需求 在顶层架构师设定好的框架下 做着重复且无聊的编码工作 如果未来ai被广泛应用 那么被替代的风险是很高的 比较扎心的是 其实目前用ai生成片段代码已经是各个公司比较普遍的做法了
  • C++设计模式 #3策略模式(Strategy Method)

    动机 在软件构建过程中 某些对象使用的的算法可能多种多样 经常改变 如果将这些算法都写在类中 会使得类变得异常复杂 而且有时候支持不频繁使用的算法也是性能负担 如何在运行时根据需求透明地更改对象的算法 将算法和对象本身解耦 从而避免上述问题
  • 2023 年精选:每个 DevOps 团队都应该了解的 5 种微服务设计模式

    微服务彻底改变了应用程序开发世界 将大型整体系统分解为更小 更易于管理的组件 这种架构风格的特点是独立 松散耦合的服务 带来了从可扩展性 模块化到更高的灵活性等众多优势 DevOps 团队如何最好地利用这种方法来实现最高效率 答案在于理解并

随机推荐

  • B站自动搜索关键词,并自动评论+点赞+收藏

    我将代码分成四部分 分别是评论 comment 获取视频网站 geturl 点赞 like 和主要调用 main 以及收藏 shoucang 灵感来自 看嘉然二创的时候下面有时候会有评论 然后机器人自动回复 并计算这是今天第几个视频 于是写
  • Netty保姆级教程(一)IO 演变

    目录 1 内核态与用户态切换 2 基于 BIO 设计的 Socket 示例 3 OS 指令上 BIO 阻塞验证 系统调用 strace 参数设置 4 NIO代码示例 总结下 BIO 与 NIO 5 BIO NIO 的模型图 6 IO 多路复
  • 记一次MongoDB的aggregate使用

    MongoDB聚合使用 包括二次聚合 aggregate 方法 语法 常用聚合表达式 管道的概念 常用聚合操作 聚合实例 根据时间聚合 二次聚合 aggregate 方法 MongoDB中使用 aggregate 方法进行聚合处理 例如统计
  • matlab相机标定知识整理

    matlab相机标定知识整理 单目相机标定 单目相机标定 内参矩阵 cameraParams Intrinsics K 或者 cameraParams K 旋转矩阵 cameraParams RotationMatrices 有待确定 ca
  • ElasticSearch6.8.4&kibana6.8.4 安装教程

    引言 客户机装的 ElasticSearch 6 8 4 所以本地安装单机测试使用 故而记录一下 虚拟机内的Linux版本为 centos7 依赖环境配置 安装JDK 安装JDK教程 可看我这篇文章 https blog csdn net
  • CSS 中过渡动画(transition)的使用

    博主前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住也分享一下给大家 点击跳转到网站 前言 通过模仿进度条进度 来练习使用过渡动画 HTML代码如下
  • 【云原生】k8s的集群调度

    k8s中的list watch机制 1 1 list watc机制的概念运用 Kubernetes 是通过 List Watch 的机制进行每个组件的协作 保持数据同步的 每个组件之间的设计实现了解耦 用户是通过 kubectl 根据配置文
  • Pandas处理Excel超简单

    前言 前几天有朋友咨询我关于学习 Python 和 VBS 的疑问 因为他想要将自己繁杂的 Excel 操作自动化 他了解到通过 Python 和 VBS 都可以达到他的目的 所以他在纠结到底学哪个 因为我就是搞 Python 得嘛 所以我
  • 使用matlab写二维数字波束形成程序并输出

    使用 MATLAB 写二维数字波束形成程序的步骤是 1 使用离散傅立叶变换 DFT 计算输入信号的频谱 2 计算波束形成器的权重矩阵 3 使用矩阵乘法计算输出信号的频谱 4 使用逆离散傅立叶变换 IDFT 计算输出信号 最后 输出信号就是二
  • 多态的概念、定义以及实现

    多态的概念 1 多态 多态的概念 通俗来说 就是多种形态 具体点就是去完成某个行为 当不同的对象去完成时会产生出不同 的状态 2 举个栗子 比如买票这个行为 当普通人买票时 是全价买票 学生买票时 是半价买票 军人买票时是优 先买票 再举个
  • OBCP考试经验分享

    1 考试大纲 2 考试范围 官方文档 教材 视频 obcp模拟试题 2题左右 实验手册 3 考试总结 备份恢复占比很少 1道题左右 分布式事务 2道题左右 参与者 协调者 分布式架构 4道题左右 租户 资源池 unit创建扩容 Sql引擎
  • tril--下三角矩阵的抽取

    功能简介 抽取下三角矩阵 语法格式 L tril X k 抽取矩阵中第k条对角线及其以下的元素 k 0指主对角线 k gt 0指主对角线以上的第k条对角线 k lt 0指主对角线以下的第k条对角线 格式变体 L tril X 返回矩阵的下三
  • FFMPEG转码后得到的MP4必须要加载完才能播放的问题

    使用videoview时出现提示 不适合在此设备上播放 但是下载之后又可以播 百思不解 还是看下高人的解决方法 FFMpeg转码由此得到的mp4文件中 meta信息是在文件尾部的 而 videoview 在没有得到meta信息前不会播放文件
  • c++ decltype推导类型

    一 decltype关键字简介 在C 11中 decltype 是一个操作符 用于查询表达式的数据类型 而不会计算实际执行表达式的值 其语法如下 decltype expression var decltype 分析表达式并推导出其类型 它
  • Java中的String,这一篇就够了

    目录 1 String的重要性 2 常用语法 2 1字符串构造 2 2 String对象的比较 2 3 字符串查找 2 4 转化 2 5字符串替换 2 6字符串拆分 示例1 实现字符串的拆分处理 示例2 字符串的部分拆分 示例3 拆分IP地
  • python爬虫从入门到精通

    目录 一 正确认识Python爬虫 二 了解爬虫的本质 1 熟悉Python编程 2 了解HTML 3 了解网络爬虫的基本原理 4 学习使用Python爬虫库 三 了解非结构化数据的存储 1 本地文件 2 数据库 四 掌握各种技巧 应对特殊
  • Vue3中如何点击外部button进行van-form表单验证

    Vue3中如何点击外部button进行表单验证 1 html页面 1 1 代码 1 2 注意项 2 JS部分核心代码 1 html页面 1 1 代码
  • Echarts双x轴不等分堆叠柱状图加折线

    效果图 核心配置 在指定x轴显示柱状图 1 series data数据格式 value x轴名称 117 第一项代表在x轴显示的下标位置 117为数据量 每个柱状图都显示单独的名称 1 在首组数据前再添加一项数据 数据量为0 视图就无法显示
  • Biggest Number深搜

    Description You have a maze with obstacles and non zero digits in it You can start from any square walk in the maze and
  • 【设计模式】装饰器模式

    装饰器模式 Decorator Pattern 允许向一个现有的对象添加新的功能 同时又不改变其结构 这种类型的设计模式属于结构型模式 它是作为现有的类的一个包装 装饰器模式通过将对象包装在装饰器类中 以便动态地修改其行为 这种模式创建了一