【设计模式】之装饰器模式

news/2024/9/25 23:20:50/

系列文章目录


前言

今天给大家介绍23种设计模式中的装饰器模式。🌈

一、什么是装饰器模式

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

装饰器模式中,有一个抽象组件接口,所有具体组件和装饰器都实现了这个接口。装饰器持有一个指向抽象组件的引用,并通过递归的方式调用接口中的操作。每个装饰器都可以添加自己的功能,同时调用所装饰的对象的操作。

二、装饰器模式的角色

Component(抽象组件)定义了一个对象的接口,可以给这些对象动态地添加职责(即方法)
ConcreteComponent(具体组件)实现了Component接口,是装饰器要装饰的真实对象
Decorator(装饰器)
  • 持有一个指向Component对象的引用,并有一个和Component接口一致的接口。
  • 它可以给组件添加额外的职责(方法)。
  • 通常包含对Component对象的引用以及实现Component接口的方法,这些方法会调用Component接口中定义的操作,并可能在其前后添加新的行为
ConcreteDecorator(具体装饰器)实现了Decorator接口,是装饰器接口的具体实现类

三、示例

定义一个抽象组件:

java">public interface Person {Double cost();void show();
}

具体组件:

java">public class XiaoJie implements Person{@Overridepublic Double cost() {return 0.0;}@Overridepublic void show() {System.out.println("没穿衣服的小杰。");}
}

 定义装饰器

java">public abstract class ClothesDecorator implements Person{protected Person person;public ClothesDecorator(Person person) {this.person = person;}
}

 具体装饰器:

java">public class Shirt extends ClothesDecorator{public Shirt(Person person) {super(person);}@Overridepublic Double cost() {return this.person.cost()+500;}@Overridepublic void show() {this.person.show();System.out.println("买了一个体恤,累计消费:" + this.cost() + "元");}
}public class Jeans extends ClothesDecorator{public Jeans(Person person) {super(person);}@Overridepublic Double cost() {return this.person.cost()+200.0;}@Overridepublic void show() {this.person.show();System.out.println("买了一条牛仔裤,累计消费:"+this.cost()+"元");}
}public class Shoes extends ClothesDecorator{public Shoes(Person person) {super(person);}@Overridepublic Double cost() {return this.person.cost()+1000.0;}@Overridepublic void show() {this.person.show();System.out.println("买了一双鞋,一共消费:"+this.cost()+"元");}
}

测试:

java">public class test {public static void main(String[] args) {Person xiaoJie = new XiaoJie();xiaoJie = new Shirt(xiaoJie);xiaoJie = new Jeans(xiaoJie);xiaoJie = new Shoes(xiaoJie);xiaoJie.show();System.out.println("本次一共消费:"+xiaoJie.cost()+"元");}
}
/*
测试结果:没穿衣服的小杰。
买了一个体恤,累计消费:500.0元
买了一条牛仔裤,累计消费:700.0元
买了一双鞋,一共消费:1700.0元
本次一共消费:1700.0元*/

 四、应用场景

  1. 扩展类的功能:当需要给一个已经存在的类添加新的功能,但又不想通过继承来生成子类时,可以使用装饰器模式。这是因为继承会增加类的层次结构,可能导致类的数量爆炸式增长,而装饰器模式可以在不改变原有类结构的情况下,动态地给对象添加新的功能。
  2. 动态添加和撤销功能装饰器模式允许在运行时动态地给对象添加新的功能,并且这些功能也可以动态地被撤销。这对于那些需要经常变化或需要灵活配置的功能来说非常有用。
  3. 为一组相似的类添加功能:如果有一组相似的类,它们都需要添加相同的功能,但是又不希望修改这些类的源代码,那么可以使用装饰器模式。通过为这些类创建一个统一的接口或抽象类,并创建一个装饰器类来包装这些类的对象,就可以在保持原有类结构不变的情况下,为这些类添加新的功能。
  4. 处理透明性和递归组合装饰器模式可以透明地添加或撤销功能,这意味着用户在使用被装饰的对象时,不需要知道对象是否被装饰过。此外,装饰器模式还可以实现递归组合,即一个装饰器可以包含另一个装饰器,从而创建出更复杂的功能组合。

在实际应用中,装饰器模式可以用于许多场景,例如:

  • 在图形界面库中,可以使用装饰器模式来动态地改变控件的外观或行为。
  • 在网络编程中,可以使用装饰器模式来添加日志记录、性能监控等功能到现有的网络请求或响应对象中。
  • 在游戏开发中,可以使用装饰器模式来扩展游戏角色的能力或属性。
  • 在Web应用中,可以使用装饰器模式来动态地添加或撤销用户的权限或角色。

总之,装饰器模式是一种非常灵活和强大的设计模式,它可以在不改变现有类结构的情况下,动态地给对象添加新的功能或职责。

五、总结

优点

  • 动态扩展装饰器模式允许在运行时动态地给一个对象添加新的功能或职责,而无需修改其原有结构。这使得代码更加灵活和可扩展。

  • 高内聚低耦合:通过组合而非继承来扩展对象的功能,有助于保持类的职责单一,实现高内聚。同时,由于装饰器与被装饰对象之间通过接口或抽象类进行交互,降低了它们之间的耦合度。

  • 透明性:对于使用装饰器模式的客户端代码来说,装饰过的对象与未装饰的对象在接口上是一致的,因此可以透明地使用装饰过的对象。客户端无需知道对象是否被装饰过,也无需关心装饰的具体细节。

  • 灵活性装饰器模式允许在运行时通过组合不同的装饰器来创建具有不同功能组合的对象。这使得可以根据需要灵活地定制对象的行为。

缺点

  • 可能产生较多的对象:由于装饰器模式是通过组合多个装饰器来扩展对象的功能的,因此在使用时可能会产生较多的对象。这可能会导致内存占用增加和性能下降的问题。

  • 对装饰器的要求:装饰器需要与被装饰对象具有相同的接口或抽象类。如果接口或抽象类发生变化,可能需要修改所有的装饰器。这可能会增加维护成本。

  • 可能导致设计过度复杂化:如果过度使用装饰器模式,可能会导致设计过度复杂化。过多的装饰器类和接口可能会使代码难以理解和维护。

  • 递归调用:在某些情况下,装饰器可能会递归地调用自身或其他装饰器。这可能会导致无限递归或栈溢出的问题,需要特别注意。


总结

今天的分享就到这里,我们下期再见✋


http://www.ppmy.cn/news/1453925.html

相关文章

数据结构---时间复杂度+空间复杂度

算法(algorithm)简单说就是解决问题的方法。方法有好坏,同样算法也是,有效率高的算法,也有效率低的算法。衡量算法的好坏一般从时间和空间两个维度衡量,也就是本文要介绍的时间复杂度和空间复杂度。有些时候,时间与空间…

Git 保姆级教程(二):Git 分支

一、分支简介 1.1 git branch name(创建分支) 比如,创建一个 testing 分 支, 你需要使用 git branch 命令: [rootlocalhost git_study]# git branch testing 你可以简单地使用 git log 命令查看各个分支当前所指的…

大数据信用花了,一般多久能正常?

在当今数字化时代,大数据技术被广泛应用于各个领域,包括金融、电商、社交等。然而,随着大数据技术的普及,个人信用问题也日益凸显,其中“大数据信用花”现象尤为引人关注。那么,大数据信用花究竟是什么?一…

软工导论第三章 需求分析

对软件需求的深人理解是软件开发工作获得成功的前提条件,不论人们把设计和编码工作做得如何出色,不能真正满足用户需求的程序只会令用户失望,给开发者带来烦恼。(意义) 需求分析是软件定义时期的最后一个阶段,它的基本任务是准确地回答“系统必须做什么”…

5月4(信息差)

🎄 HDMI ARC国产双精度浮点dsp杜比数码7.1声道解码AC3/dts/AAC环绕声光纤、同轴、USB输入解码板KC33C 🌍 国铁集团回应高铁票价将上涨 https://finance.eastmoney.com/a/202405043066422773.html ✨ 源代码管理平台GitLab发布人工智能编程助手DuoCha…

python数据分析——大数据伦理风险分析

大数据伦理风险分析 前言一、大数据伦理二、大数据技术伦理风险2.1算法安全性、可信赖性及稳定性风险及其应对2.2算法的可解释性风险及其应对2.3算法的决策不可预见性风险及其应对2.4数据收集与储存中的泄漏风险及其应对2.5案例:某大型电商平台内部员工涉嫌窃取50亿…

农作物害虫检测数据集VOC+YOLO格式18975张97类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):18975 标注数量(xml文件个数):18975 标注数量(txt文件个数):18975 标…

【微服务】服务治理(Nacos注册中心)

服务治理 服务治理注册中心Nacos注册中心服务注册服务发现 服务治理 RestTemplate进行服务间的相互调用是非常有问题的,如果服务备份多个服务器,进行集群服务,而且在开发阶段,我们也不知道其它服务器的地址,那这时我们…