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

结构设计模式 -装饰器设计模式 - JAVA

装饰器设计模式

    • 一. 介绍
    • 二. 代码示例
      • 2.1 抽象构件(Component)角色
      • 2.2 具体构件(Concrete Component)角色
      • 2.3 装饰(Decorator)角色
      • 2.4 具体装饰(Concrete Decorator)角色
      • 2.5 测试 结果
    • 三. 结论
      • 3.1 优缺点
      • 3.2 使用场景

前言
这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。

作者:神的孩子都在歌唱

一. 介绍

百度百科装饰模式指的是在不必改变原类文件使用继承的情况下,动态扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象

个人理解: java在编译完成后,我们无法动态的去为一个编译好的对象新增或者修改某个功能,这时候就可以通过装饰模式去设计

举例理解: 通常我们使用继承或者组合去扩展对象的行为,假如我们想要实现不同种类的手链,我们创建一个手链(Bracelet)接口,然后我们通过实现这个接口获取一个基本的手链(basic bracelet),我们可以在基本的手链的基础上进行扩展获得**金手链(Gold)和银手链(Silver)**结构图如下所示。

请添加图片描述

通过以上案例我们可以了解到,一些简单的扩展通过继承的方式就可以解决了,但如果我们还想在扩展,想要获取一个同时具备金色和银色的手链,并且还要添加某些功能,那么就会变得很复杂。如果手链类型增加,使用继承的实现逻辑就很难管理。这时候就可以通过装饰模式去设计

好了,上面的介绍都是再讲为什么要使用装饰模式,接下来就通过代码案例讲解装饰模式是怎么样子实现的,如何解决上面所说的问题

装饰模式有以下角色:

(1)抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。

(2)具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。

(3)装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。

(4)具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。

二. 代码示例

装饰模式代码具体流程如下

请添加图片描述

2.1 抽象构件(Component)角色

定义要实现的方法的接口或抽象类

/*** @author chenyunzhi* @date 2024/6/3 16:06* @Description 手链*/
public interface Bracelet {void color();}

2.2 具体构件(Concrete Component)角色

/*** @author chenyunzhi* @date 2024/6/3 16:08* @Description 基本的手链,也就是白色*/
public class BasicBracelet implements Bracelet{@Overridepublic void color() {System.out.print("基本的白色手链");}
}

2.3 装饰(Decorator)角色

/*** @author chenyunzhi* @date 2024/6/3 16:23* @Description 手链装饰器*/
public class BraceletDecorator implements Bracelet {/*** 装饰器类应该可以访问组件变量,因此我们将保护该变量*/protected Bracelet bracelet;public BraceletDecorator(Bracelet bracelet) {this.bracelet = bracelet;}@Overridepublic void color() {this.bracelet.color();}
}

2.4 具体装饰(Concrete Decorator)角色

金手链

/*** @author chenyunzhi* @date 2024/6/3 16:32* @Description 金手链*/
public class GoldBracelet extends BraceletDecorator{public GoldBracelet(Bracelet bracelet) {super(bracelet);}@Overridepublic void color() {super.color();System.out.print(",增加金色");}
}

银手链

/*** @author chenyunzhi* @date 2024/6/3 16:37* @Description 银手链*/
public class SilverBracelet extends BraceletDecorator{public SilverBracelet(Bracelet bracelet) {super(bracelet);}@Overridepublic void color() {super.color();System.out.print(",增加银色");}
}

2.5 测试 结果

/*** @author chenyunzhi* @date 2024/6/3 14:39* @Description*/
public class DecoratorPatternTest {public static void main(String[] args) throws Exception{// 获取金手链对象Bracelet goldBracelet = new GoldBracelet(new BasicBracelet());goldBracelet.color();System.out.println("\n-----------------------");// 获取银手链对象Bracelet silverBracelet = new SilverBracelet(new BasicBracelet());silverBracelet.color();System.out.println("\n-----------------------");// 获取包含金色和银色的手链Bracelet goldSilverBracelet = new GoldBracelet(new SilverBracelet(new BasicBracelet()));goldSilverBracelet.color();}
}

请添加图片描述

通过以上结果我们可以看到,如果我们想要获取包含 金色和银色的手链,可以通过组合金色和银色的装饰者对象来获取具有金色和银色手链。

三. 结论

3.1 优缺点

优点:

  • 装饰器设计模式有助于提供运行时修改能力,因此更加灵活。当选择数量较多时,易于维护和扩展。
  • 装饰器设计模式的缺点是它使用了很多相似类型的对象(装饰器)。
  • Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
  • 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点

  • 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
  • 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
  • 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

3.2 使用场景

  • 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。

    不能采用继承的情况主要有两类:

    • 第一类是系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;
    • 第二类是因为类定义不能继承(如final类)
  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

  • 当对象的功能要求可以动态地添加,也可以再动态地撤销时。

  • 装饰器模式在Java IO类中被大量使用,例如FileReader、BufferedReader等。

作者:神的孩子都在歌唱

本人博客:https://blog.csdn.net/weixin_46654114

转载说明:务必注明来源,附带本人博客连接。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 技术美术百人计划 | 《5.1.2 PBR-基于物理的相机》笔记
  • 百易云资产管理运营系统 ticket.edit.php SQL注入漏洞复现
  • 前端基于Rust实现的Wasm进行图片压缩的技术文档
  • 网络分段:您需要了解的一切
  • WEB攻防-JavaWweb项目JWT身份攻击组件安全访问控制
  • Java的cnum类型
  • Zabbix 6.4添加中文语言
  • 第一次见到要主动降薪的。。。
  • 【Vue系列五】—Vue学习历程的知识分享!
  • Qt上下文菜单
  • docker快速部署zabbix
  • 开源UNI-SOP云统一认证平台
  • 信息技术的革新与未来趋势
  • nodejs基于vue电子产品商城销售网站的设计与实现 _bugfu
  • 图文组合商标部分驳回后优化后初审通过!
  • [译]Python中的类属性与实例属性的区别
  • 2017-08-04 前端日报
  • Apache Spark Streaming 使用实例
  • C++入门教程(10):for 语句
  • jQuery(一)
  • Laravel 实践之路: 数据库迁移与数据填充
  • tensorflow学习笔记3——MNIST应用篇
  • vue-cli3搭建项目
  • Vue官网教程学习过程中值得记录的一些事情
  • Webpack 4 学习01(基础配置)
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • - 转 Ext2.0 form使用实例
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • # 数据结构
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #pragma pack(1)
  • (70min)字节暑假实习二面(已挂)
  • (AngularJS)Angular 控制器之间通信初探
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (转)fock函数详解
  • (转)linux 命令大全
  • (转)大型网站的系统架构
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • (最新)华为 2024 届秋招-硬件技术工程师-单板硬件开发—机试题—(共12套)(每套四十题)
  • ***检测工具之RKHunter AIDE
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .bat批处理出现中文乱码的情况
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .Net Remoting常用部署结构
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • .vimrc 配置项
  • /etc/skel 目录作用
  • @Autowired @Resource @Qualifier的区别