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

server/2024/9/24 22:18:59/

装饰器设计模式

    • 一. 介绍
    • 二. 代码示例
      • 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)角色

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

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

2.2 具体构件(Concrete Component)角色

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

2.3 装饰(Decorator)角色

java">/*** @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)角色

金手链

java">/*** @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(",增加金色");}
}

银手链

java">/*** @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 测试 结果

java">/*** @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

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


http://www.ppmy.cn/server/121530.html

相关文章

数理统计(第一章)

数理统计核心问题:有子样推断母体 1.1 母体和子样 母体:研究对象的全体(关心个体的一项或者几项)数量指标及总体的分布情况。 比如:一批灯泡的使用寿命,班级学生的身高,体重等。 1.2 母体分布…

Spring MVC 基本配置步骤 总结

1.简介 本文记录Spring MVC基本项目拉起配置步骤。 2.步骤 在pom.xml中导入依赖&#xff1a; <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>6.0.6</version><scope>…

类型转换与RTTI

类型转换 一、类型转换1、C语言2、C3、注意 二、static_cast1、介绍2、示例 三、reinterpret_cast1、介绍2、示例代码3、运行结果 四、const_cast1、介绍2、示例 五、dynamic_cast1、介绍2、示例代码3、运行结果 六、RTTI1、介绍2、typeid&#xff08;1&#xff09;介绍&#x…

LabVIEW提高开发效率技巧----合理使用数据流与内存管理

理使用数据流和内存管理是LabVIEW开发中提高性能和稳定性的关键&#xff0c;特别是在处理大数据或高频率信号时&#xff0c;优化可以避免内存消耗过大、程序卡顿甚至崩溃。 1. 使用 Shift Register 进行内存管理 Shift Register&#xff08;移位寄存器&#xff09; 是 LabVIE…

《DevOps实践指南》笔记-Part 3

一篇文章显得略长&#xff0c;本文对应第5-6章、附录、认证考试、参考资源等。 前言、第1-2章请参考Part 1&#xff0c;第3-4章内容&#xff0c;请参考Part 2。 持续学习与实验的技术实践 通过以下方式制定有关提高安全性、持续改进和边做边学的制度&#xff1a; 建立公正的…

分布式消息服务Kafka版的详细解析和配置方式

分布式消息服务Kafka版是一款基于开源社区版Kafka提供的消息队列服务&#xff0c;它向用户提供计算、存储和带宽资源独占式的Kafka专享实例。以下是对分布式消息服务Kafka版的详细解析和配置方式的介绍。 一、分布式消息服务Kafka版解析 1. Kafka概述 Kafka是一个开源的分布…

CSS调整背景

一、设置背景颜色 通过 background-color 属性指定&#xff0c;值可以是十六进制 #ffffff&#xff0c;也可以是rgb(0, 255, 255)&#xff0c;或是颜色名称 "red" div {background-color: red; /* 通过颜色名称设置 */background-color: #ff0000; /* 通过十六进制设…

oracle表的类型

表是数据库最基本的逻辑结构&#xff0c;一切数据都存放在表中&#xff0c;其它数据库对象(索引、视图、同义词等)都是为了更方便的操作表中的数据。Oracle数据库是由若干个表组成&#xff0c;每个表由列和行组成。 数据库表的类型按照存储结构划分&#xff1a; (1)普通表&…