Android设计模式--装饰模式

   千淘万漉虽辛苦,吹尽黄沙始到金

一,定义

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

装饰模式也叫包装模式,结构型设计模式之一,其使用一种对客户端透明的方式来动态地扩展对象的功能,同时它也是继承关系的一种替代方案之一。

二,使用场景

需要透明且动态的扩展类的功能时。

装饰模式在代码中的应用非常广泛,我们在不经意间就会使用到类似的概念。比如:

public abstract class EtnApplication extends Application {@Overridepublic void onCreate() {super.onCreate();setRxJavaErrorHandler();initApplication();}private void initApplication(){}private void setRxJavaErrorHandler(){}
}

这里的setRxJavaErrorHandler 和initApplication 就是对onCreate方法的包装

三,角色介绍

1,Component:抽象组件

可以是一个接口或者抽象类,其充当的就是被装饰的原始对象

2,ConcreteComponent:组件具体实现类

该类是Component类的基本实现,也是我们装饰的具体对象

3,Decorator:抽象装饰者

其承担的职责就是为了装饰我们的组件对象,其内部一定要有一个指向组件对象的引用。在大多数情况下,该类为抽象类,需要根据不同的装饰逻辑实现不同的具体子类。当然,如果装饰逻辑单一,只有一个的情况下我们可以省略该类直接作为具体的装饰者

4,ConcreteDecorator:装饰者具体实现类

只是对抽象装饰者作出具体的实现

四,使用案例

在和平精英吃鸡手游这个游戏的玩家群体里,大部分人玩游戏都是自己一个人玩,有一部分人为了上分会花钱请一些技术陪玩一起玩,还有一部分人玩游戏不是为了上分,而是为了开心,他们会花钱请一些娱乐陪玩一起玩。

在这里,我们就可以将玩家定义为一个抽象类,将玩家玩游戏的行为定义为一个具体的方法,这就是上面提到的抽象组件:

public abstract class Player {/*** 玩游戏* */public abstract void playGame();
}

然后具体实现类就是具体到某个人,继承抽象组件:

public class YuanZhen extends Player{@Overridepublic void playGame() {System.out.println("玩吃鸡游戏");}
}

然后创建一个抽象的装饰者类:

public abstract class PlayerAbsDecorator extends Player{protected Player player;public PlayerAbsDecorator(Player player) {this.player = player;}@Overridepublic void playGame() {player.playGame();}
}

这个类是该模式的核心类,它持有了Player的引用,可以方便的调用具体被装饰对象中的方法,这也是为什么我们可以在不破坏原类层次结构的情况下为类增加一些功能,我们只需在被装饰对象的相应方法的前或后增加相应的功能逻辑即可。

最后创建我们的具体装饰者类,继承抽象装饰者类,实现技术陪玩和娱乐陪玩相关方法

public class TechnicalPlayer extends PlayerAbsDecorator{public TechnicalPlayer(Player player) {super(player);}public void eatChicken(){System.out.println("吃鸡了");}@Overridepublic void playGame() {super.playGame();eatChicken();}
}
public class EntertainmentPlayer extends PlayerAbsDecorator{public EntertainmentPlayer(Player player) {super(player);}private void happy(){System.out.println("玩的开心");}@Overridepublic void playGame() {super.playGame();happy();}
}

使用:

YuanZhen yuanzhen=new YuanZhen();
EntertainmentPlayer entertainmentPlayer =new EntertainmentPlayer(yuanzhen);
entertainmentPlayer.playGame();
TechnicalPlayer technicalPlayer =new TechnicalPlayer(yuanzhen);
technicalPlayer.playGame();

输出:

这样就实现了一个简单的装饰者模式。

五,总结

装饰者模式和代理模式Java 代理模式之静态代理与动态代理_java静态代理模式_袁震的博客-CSDN博客有点类似,有时容易混淆。

注意:装饰模式是以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,而代理模式则是给一个对象提供一个代理对象,并有代理对象来控制原有对象的引用。装饰模式应该为所装饰的对象增强功能,代理模式对代理的对象施加控制,但不对对象本身的功能进行增强。

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

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

相关文章

<JavaEE> 什么是线程(Thread)?进程和线程有什么区别?

目录 一、线程(Thread)的概念 二、线程存在的意义 2.1 并发编程 2.2 比进程更“轻量” 三、使用线程时应该注意 四、进程和线程的区别 五、Java中的线程和操作系统中的线程是不同的概念 六、多线程编程 一、线程(Thread)的…

图神经网络的数学原理总结

图深度学习(Graph Deep Learning) 多年来一直在加速发展。许多现实生活问题使GDL成为万能工具:在社交媒体、药物发现、芯片植入、预测、生物信息学等方面都显示出了很大的前景。 本文将流行的图神经网络及其数学细微差别的进行详细的梳理和解释,图深度学…

Linux中flask项目开启https访问

1.下载阿里云免费证书 2.项目添加https配置 3.服务器开启https访问 3.1 重新安装OpenSSL 3.2.重新安装Python 上一次已经讲过Linux安装部署Python: Linux安装Python3.10与部署flask项目实战详细记录,今天记录一下Python项目如何支持https访问…

性能相关的闪存特性

一、多Plane操作 上章提到若干个Plane组成Die或者叫LUN,即一个Die上有多个Plane 每次进行写操作时,控制器先将数据写入页缓存中,等同一个Die上另一个Plane也写数据的时候,再同时写入,原来单独操作一个Plane的时间变成了可以同时做…

Springmvc实现增删改差

一、包结构 二、各层代码 (1)数据User public class User {private Integer id;private String userName;private String note;public User() {super();}public User(Integer i, String userName, String note) {super();this.id i;this.userName userName;this.note note;…

Qt实现自定义IP地址输入控件(百分百还原Windows 10网络地址输入框)

在开发网络相关的程序时,我们经常需要输入IP地址,例如源地址和目标地址。Qt提供了一些基础的控件,如QLineEdit,但是它们并不能满足我们对IP地址输入的要求,例如限制输入的格式、自动跳转到下一个输入框、处理回车和退格键等。因此,我们需要自己编写一个自定义的IP地址输入…

【赠书第7期】从零基础到精通Flutter开发

文章目录 前言 1 安装Flutter和Dart 2 了解Flutter的基础概念 2.1 Widget 2.2 MaterialApp和Scaffold 2.3 Hot Reload 3 编写你的第一个Flutter应用 3.1 创建一个Flutter项目 3.2 修改默认页面 3.3 添加交互 4 深入学习Flutter高级特性 4.1 路由和导航 4.2 状态管…

python之TCP的网络应用程序开发

文章目录 版权声明python3编码转换socket类的使用创建Socket对象Socket对象常用方法和参数使用示例服务器端代码客户端代码 TCP客户端程序开发流程TCP服务端程序开发流程TCP网络应用程序注意点socket之send和recv原理剖析send原理剖析recv原理剖析send和recv原理剖析图 多任务版…

在两个java项目中实现Redis的发布订阅模式

如何在两个java项目中实现Redis的发布订阅模式? 1. Redis简介2. 发布订阅模式介绍3. 实现思路4. 代码实现及详细解释4.1. RedisUtil4.2. Publisher4.3. Subscriber4.4. 运行程序 目录: Redis简介发布订阅模式介绍实现思路代码实现及详细解释 1. Redis简…

HTB Napper WriteUp

Napper 2023年11月12日 14:58:35User Nmap ➜ Napper nmap -sCV -A -p- 10.10.11.240 --min-rate 10000 Starting Nmap 7.80 ( https://nmap.org ) at 2023-11-12 13:58 CST Nmap scan report for app.napper.htb (10.10.11.240) Host is up (0.15s latency). Not shown: …

适用于电脑的5个免费文件恢复软件分享

适用于电脑的最佳免费文件恢复软件 任何计算机用户都可能经历过丢失重要文件的恐惧。重要数据的丢失可能会令人不安和沮丧,无论是由于不小心删除、计算机故障还是硬盘格式化造成的。幸运的是,在数字时代,您可以使用值得信赖的解决方案检索这些…

好工具|datamap,一个好用的地图可视化Excel插件,在Excel中实现地理编码、拾取坐标

在做VRP相关研究的时候,需要对地图数据做很多处理,比如地理编码,根据“重庆市沙坪坝区沙正街174号”这样的一个文本地址知道他的经纬度;再比如绘制一些散点图,根据某个位置的经纬度在地图上把它标注出来。还有有的时候…

vue + docxtemplater 导出 word 文档

一、痛点 word 导出 这种功能其实之前都是后端实现的,但最近有个项目没得后端。所以研究下前端导出。 ps: 前端还可以导出 pdf,但是其分页问题需要话精力去计算才可能实现,并且都不是很完善。可参考之前的文章:利用 h…

JavaScript框架 Angular、React、Vue.js 的全栈解决方案比较

在 Web 开发领域,JavaScript 提供大量技术栈可供选择。其中最典型的三套组合,分别是 MERN、MEAN 和 MEVN。前端框架(React、Angular 和 Vue)进行简化比较。 MERN 技术栈详解 MERN 技术栈包含四大具体组件: MongoDB&am…

蓝桥杯物联网竞赛_STM32L071_3_Oled显示

地位: 对于任何一门编程语言的学习,print函数毫无疑问是一种最好的调试手段,调试者不仅能通过它获取程序变量的运行状态而且通过对其合理使用获取程序的运行流程,更能通过关键变量的输出帮你验证推理的正确与否,朴素的…

常见网络安全防护

1 阻断服务攻击(DOS) 阻断服务攻击,想办法目标网络资源用尽变种:分布式阻断服务攻击 影响: 宽带消耗性(消耗目标的带宽)资源消耗型(消耗目标的计算资源) 解决方案&am…

人工智能对网络安全的影响越来越大

如果问当前IT行业最热门的话题是什么,很少有人会回答除了人工智能(AI)之外的任何话题。 在不到 12 个月的时间里,人工智能已经从一项只有 IT 专业人员才能理解的技术发展成为从小学生到作家、程序员和艺术家的每个人都使用的工具…

MySQL索引事务基础

目录 1. 索引 1.1索引的概念 1.2索引的特点 1.3 索引的使用场景 1.4索引的使用 1.4.1查看索引 1.4.2创建索引 1.4.3删除索引 1.5索引保存的数据结构 2.事务 2.1经典例子 2.2事务的概念 2.3事务的使用 2.4事务的4个核心特性 2.5事务的并发问题 2.5.1脏读 2.5.2不可…

Python + Docker 还是 Rust + WebAssembly?

在不断发展的技术世界中,由大语言模型驱动的应用程序,通常被称为“LLM 应用”,已成为各种行业技术创新背后的驱动力。随着这些应用程序的普及,用户需求的大量涌入对底层基础设施的性能、安全性和可靠性提出了新的挑战。 Python 和…

Java项目如何打包成Jar(最简单)

最简单的办法,使用Maven插件(idea自带) 1.选择需要打包的mudule,点击idea右侧的maven插件 2.clean操作 3.选择需要的其他mudule,进行install操作(如果有) 4.再次选择需要打包的module&#…