结构型模式-装饰模式

装饰模式是什么

     装饰模式是一种结构型设计模式,它允许你向一个对象添加新的功能,而无需修改原始类的代码。通过将对象包装在一个装饰器类中,你可以在运行时动态地添加、修改或删除对象的行为。

装饰模式基于组合而非继承的原则,它的核心思想是通过创建一个装饰器类来包装原始对象,并使得装饰器类具有与原始对象相同的接口。这样一来,你可以根据需要将一个或多个装饰器类串联起来,逐层地装饰对象,从而实现一种灵活的行为扩展机制。

装饰模式优缺点

    装饰模式是一种结构型设计模式,其主要目的是在不改变原有对象的结构的情况下,动态地给对象添加职责。装饰模式通过将对象包装在装饰器对象中,以此来增强原有对象的功能。

优点:

  1. 符合开闭原则。装饰模式可以在不修改原有对象的情况下,动态地扩展对象的功能,满足“开放-封闭”原则。
  2. 更灵活。装饰模式可以动态地添加或移除功能,不同的装饰器可以组合使用,以实现不同的功能组合,提供更大的灵活性。
  3. 避免类的混乱。装饰模式可以将功能分散在不同的装饰器中,避免了将所有功能集中在一个类中,提高了代码的可读性和可维护性。

缺点:

  1. 可能导致类的数量增多。每个装饰器都需要一个对应的具体装饰器类,如果需要添加大量的功能,可能会导致类的数量急剧增加,增加了代码的复杂性。
  2. 可能引入过多的细粒度对象。装饰模式的实现常常需要引入大量的细粒度对象,这可能会增加系统的复杂性和内存的消耗。
  3. 装饰器的顺序问题。如果装饰器的顺序出错,可能会导致系统功能的错误,因此需要开发人员对装饰器的使用进行仔细的设计和控制。

装饰模式应用场景

  1. 扩展一个类的功能或者给一个类添加附加职责。

  2. 动态地给一个对象添加功能,这些功能可以在运行时动态地进行添加、撤销。

  3. 需要为一组类提供一些额外的公共行为,而不影响这些类的结构。

  4. 需要在不影响其他对象的情况下,以动态、透明的方式给对象添加功能。

  5. 需要给对象添加一些额外的行为,但是使用继承来实现会导致类的个数急剧增加。

  6. 需要在不改变已有代码的情况下,对现有对象的功能进行动态扩展。

代码示例

首先,我们定义一个接口 Shape,表示形状:

public interface Shape {void draw();
}

然后,我们实现该接口的具体类 Circle

public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a circle");}
}

接下来,我们定义一个抽象装饰类 ShapeDecorator,它实现了 Shape 接口,并包含一个对 Shape 对象的引用:

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

然后,我们实现具体的装饰类 RedShapeDecorator,它继承自 ShapeDecorator,并可以在原始形状的基础上添加额外的功能:

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

最后,我们可以使用装饰模式来扩展现有的 Circle 类:

public class Main {public static void main(String[] args) {Shape circle = new Circle();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 with red border:");redCircle.draw();System.out.println("\nRectangle with red border:");redRectangle.draw();}
}

运行结果如下:

Circle with normal border:
Drawing a circleCircle with red border:
Drawing a circle
Border color: RedRectangle with red border:
Drawing a rectangle
Border color: Red

在上面的示例中,我们创建了一个 Circle 对象,并使用 RedShapeDecorator 对象对它进行装饰。这样,我们就在原始的 Circle 类的基础上,添加了一个红色边框的功能。同样的方法也适用于其他形状,比如 Rectangle

总结

     

装饰模式是一种结构型设计模式,它允许你通过将对象包装在一个装饰器中来动态地修改对象的行为。装饰器的接口必须与其所装饰的对象的接口一致,这样它才能透明地传递给客户端。

在装饰模式中,有一个通用的接口,用于装饰器和原始对象之间的交互。装饰器和原始对象都实现了该接口,并且装饰器内部通常会持有一个指向原始对象的引用。

装饰器可以通过在调用原始对象的方法前后添加额外的功能来扩展原始对象的行为。这种方式不仅能够在不改变原始对象代码的情况下添加新功能,还可以在运行时动态地添加或移除装饰器。

装饰模式的优点包括:可以在不修改原始对象代码的情况下增加新的功能;可以动态地添加或移除装饰器;装饰器可以透明地传递给客户端,客户端无需知道其使用的是装饰器还是原始对象。

装饰模式的缺点包括:由于装饰器和原始对象都实现了相同的接口,所以装饰器的数量可能会增加,导致类的数量增加;装饰器的排列组合可能会变得复杂,影响代码的可读性。

适用场景:

  • 当需要在不修改原始对象代码的情况下增加新的功能时,可以使用装饰模式。
  • 当需要动态地添加或移除装饰器时,可以使用装饰模式。
  • 当需要透明地传递装饰器给客户端时,可以使用装饰模式。

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

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

相关文章

KIVY Tutorials » Pong Game Tutorial¶

1Pong Game Tutorial — Kivy 2.3.0 documentation Introduction Welcome to the Pong tutorial 欢迎来到 乒乓球 导师辅导课 This tutorial will teach you how to write pong using Kivy. We’ll start with a basic application like the one described in the Create …

笔记100:使用 OSQP-Eigen 对 MPC 进行求解的方法与代码

1. 前言: 我们在对系统进行建模的时候,为了减少计算量,一般都将系统简化为线性的,系统如果有约束,也是将约束简化为线性的; 因此本篇博客只针对两种常见系统模型的 MPC 问题进行求解: 线性系统…

【Android面试八股文】你知道如何实现非阻塞式生产者消费者模式吗?

文章目录 这道题想考察什么 ?考察的知识点日常生活中的生产者消费者模式生产者消费者模式简介为什么需要缓冲区?阻塞与非堵塞非阻塞式生产者消费者模式的实现非阻塞式生产者消费者模式的实现阻塞式生产者消费者模式实现特点这道题想考察什么 ? 是否了解非阻塞式生产者消费者…

基于python实现视频和音频长度对齐合成并添加字幕

在许多视频编辑任务中,我们常常需要将视频和音频进行对齐,并添加字幕。本文将详细介绍如何使用Python实现这一功能,并在视频中添加中文字幕。我们将使用OpenCV处理视频帧,使用MoviePy处理音频和视频的合成,使用PIL库绘…

Node.js环境安装与管理指南

Node.js作为一个高效的JS运行环境,已经成为了现代Web开发的标配之一。但Node.js版本众多,不同项目可能需要不同版本的Node环境,如何管理这些版本成为了一个技术难题。本文将介绍如何使用NVM(Node Version Manager)来管…

S686量产工具授权版,S686开卡教程,S686+EMMC固态硬盘开卡量产成功记录

手里有个S686EMMC组合的固态硬盘,华澜微的S686主控,之前一直没找到工具,感觉是废了,一直放着,偶然机会从桌子里又找到它,于是继续搜寻量产工具。 找到量产部落的一篇文章,里面说首发了S686的量产…

php收银系统源码推荐

智慧新零售系统是一套线下线上一体化的收银系统。致力于给零售门店提供『多样化线下收银』、『ERP进销存』、『o2o小程序商城』、『精细化会员管理』、『丰富营销插件』等一体化行业解决方案! 一、多样化线下收银 1.聚合收款码 ①适用商户:小微门店&am…

后端高频面试题分享-用Java判断一个列表是否是另一个列表的顺序子集

问题描述 编写一个函数,该函数接受两个列表作为参数,判断第一个列表是否是第二个列表的顺序子集,返回True或False。 要求 判断一个列表是否是另一个列表的顺序子集,即第一个列表的所有元素在第二个列表需要顺序出现。列表中的元…

【实例分享】银河麒麟高级服务器操作系统环境资源占用异常-情况分析及处理方法

1.情况描述 使用vsftp进行文件传输,发现sshd进程cpu占用异常,并且su和ssh登录相比正常机器会慢2秒左右。 图1 2.问题分析 通过strace跟踪su和sshd进程,有大量ssh:notty信息。 图2 配置ssh绕过pam模块认证后,ssh连接速…

python通过selenium实现自动登录及轻松过滑块验证、点选验证码(2024-06-14)

一、chromedriver配置环境搭建 请确保下载的驱动程序与你的Chrome浏览器版本匹配,以确保正常运行。 1、Chrome版本号 chrome的地址栏输入chrome://version,自然就得到125.0.6422.142 版本 125.0.6422.142(正式版本) (…

全息图分类及相位型全息图制作方法

全息图是一种光学器件,全息图分为振幅型和相位型全息图,振幅型全息图记录光的振幅信息即强度信息,相位型全息图记录光的相位信息,利用相位信息可以恢复光的波前形状,从而记录物体形状,这里主要介绍相位全息…

【尚庭公寓SpringBoot + Vue 项目实战】图片上传(十)

【尚庭公寓SpringBoot Vue 项目实战】图片上传(十) 文章目录 【尚庭公寓SpringBoot Vue 项目实战】图片上传(十)1、图片上传流程2、图片上传接口查看3、代码开发3.1、配置Minio Client3.2、开发上传图片接口 4、异常处理 1、图片…

适合小白学习的项目1832javaERP管理系统之仓库采购管理Myeclipse开发mysql数据库servlet结构java编程计算机网页项目

一、源码特点 java erp管理系统之仓库采购管理是一套完善的web设计系统,对理解JSP java编程开发语言有帮助采用了serlvet设计,系统具有完整的源代码和数据库,系统采用web模式,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Mye…

现如今,光伏企业可以针对哪些方面实现数字化管理?

近几年的科技发展迅速,光伏企业也在现代化的背景下发展出许多智能产品,如管理系统、无人机测绘、清洁机器人等等,本文将重点讨论光伏企业实现数字化管理的内容有哪些。 一、业务管理 光伏企业在项目建设前期,首要任务就是做好选…

GitCode热门开源项目推荐:Spider网络爬虫框架

在数字化高速发展时代,数据已成为企业决策和个人研究的重要资源。网络爬虫作为一种强大的数据采集工具受到了广泛的关注和应用。在GitCode这一优秀的开源平台上,Spider网络爬虫框架凭借其简洁、高效和易用性,成为了众多开发者的首选。 一、系…

工资信息管理系统的设计

管理员账户功能包括:系统首页,个人中心,基础数据管理,公告管理,津贴管理,管理员管理,绩效管理 用户账户功能包括:系统首页,个人中心,公告管理,津…

STM32项目分享:智能窗帘系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板打样焊接图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片: 哔哩哔哩视频链接: https://www.bilibili.c…

C#观察者模式应用

目录 一、什么是观察者模式 二、C#中观察者模式的实现 三、两种实现的用法 1、事件与委托 2、IObserver和IObservable 四、参考文献 一、什么是观察者模式 观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当…

探索AIGC与3D技术的融合:从图像到可探索的3D动态场景

随着人工智能和计算机图形技术的飞速发展,AIGC(人工智能生成内容)与3D技术的结合正在为我们打开一扇全新的创意之门。最近,我深入研究了几个令人兴奋的AIGC+3D方案,它们不仅展示了从单张图片或文本提示生成3D点云的强大能力,还进一步实现了AI虚拟试穿和生成高保真3D数字人…

java对象的创建和使用

java中,定义一个类之后,需要创建该类的对象才能使用这个类 创建对象的具体格式是 类名 对象名null 对象名new 类名 这两步可以合并为一步 类名 对象名 new 类名 class Student{String name;void read() {System.out.println("大家好&#xff…