当前位置: 首页 > 后端技术 > Java

别再满屏爆炸了,试试装饰者模式吧,这才是优雅的方式!!

时间:2023-04-01 19:11:22 Java

背??景你还在写满屏爆款吗?把所有的代码都写在一个类里就行了,代码不优雅不说。如果变更涉及旧代码,也可能影响线上系统的稳定性。事实上,在很多情况下,我们可以巧妙地使用设计模式来解决很多潜在的系统问题。今天stackmanager就教大家在不改动旧代码的情况下,使用装饰器模式来扩展功能。不影响已有功能,用过的人都知道,真香!!什么是装饰者模式?Decorator模式,从字面上理解,顾名思义,就是一种装饰模式,可以在不改变原有代码的情况下,对已有的对象和行为进行全新的包装和装饰,增强原有的基础功能,提供更丰富的能力。举个简单装修的小例子:清理>腻子>油漆>挂壁画也可以是:清理>腻子>贴大理石>挂电视也可以是:清理>腻子>贴墙纸这是一个step-by-stepsimply装饰墙的过程(哈哈,大概是这样,我不是专业的),这是装饰者模式,每一步装饰互不干扰,但是后面的步骤需要依赖上一步完成后,后面的步骤就可以继续添加装饰底座了。装饰模式结构图如下:装饰模式类结构如下:Component:组件接口类,定义了被装饰类的基本功能ConcreteComponent:组件接口的基本实现类Decorator:装饰角色类,实现并持有一个Component对象实例ConcreteDecorator:类装饰器模式的优点:1、不改变原有代码,动态添加功能;2、对象之间不会相互依赖,松耦合,足够优雅;3.遵守开闭原则,扩展性好,易于维护;装饰器模式的缺点:1.如果装饰环节多,装饰器类会膨胀;2、装饰器层的嵌套比较复杂,用户必须清楚所有的装饰器类及其用途;装饰者模式实战下面我们用装饰者模式来实现上面的装饰案例。组件接口类:/***墙饰接口*@author:栈长*@from:公众号Java技术栈*/publicinterfaceWallBeautify{/***装饰操作*@author:栈长*@from:公众号Java技术栈*/voidoperation();}组件接口基础实现类:/***墙面装饰(墙面清洁)基础实现*@author:栈长*@from:公众号Java技术栈*/publicclassWallBeautifyCleanimplementsWallBeautify{@Overridepublicvoidoperation(){System.out.println("开始清墙");}}装饰器角色类:这是一个抽象类,实现并持有一个ComponentObject实例,这里使用的是聚合,而不是继承,这也是装饰器模式的要点。/***墙面装饰装饰者角色*@author:stacklength*@from:公众号Java技术栈*/publicabstractclassWallBeautifyDecoratorimplementsWallBeautify{/***持有一个Component对象实例*@author:stackLong*@来自:公众号Java技术栈*/privateWallBeautifywallBeautify;publicWallBeautifyDecorator(WallBeautifywallBeautify){this.wallBeautify=wallBeautify;}@Overridepublicvoidoperation(){wallBeautify.operation();装饰();}/***装饰器实现类自定义实现方法*@author:stacklength*@from:公众号Java技术栈*/publicabstractvoiddecoration();}覆盖原来的操作方法,然后在原来的操作之后进行装饰,所以需要为不同的装饰器实现类提供一个抽象的装饰方法来实现。装饰器的实现类:这里定义了3个装饰过程:放putty>绘画>挂壁画所以各自继承装饰器角色类并实现其装饰方法:/***墙面装饰装饰器角色实现(putty)*@author:栈长*@from:公众号Java技术栈*/publicclassWallBeautifyPuttyextendsWallBeautifyDecorator{publicWallBeautifyPutty(WallBeautifywallBeautify){super(wallBeautify);}@Overridepublicvoiddecoration(){System.out.println("开始抓取putty");}}/***墙面装饰装饰器角色实现(绘画)*@author:stacklength*@from:公众号Java技术栈*/publicclassWallBeautifyPaintextendsWallBeautifyDecorator{publicWallBeautifyPaint(WallBeautifywallBeautify){super(wallBeautify);}@Overridepublicvoiddecoration(){System.out.println("Startpainting");}}/***墙面装饰装饰者角色实现(挂壁画)*@author:Stacklength*@from:公众号Java技术栈*/publicclassWallBeautifyHangextendsWallBeautifyDecorator{}@Overridepublicvoiddecoration(){System.out.println("开始挂壁画");}}测试一下:/***Decorator模式测试类*@author:stacklength*@from:公众号Java技术栈*/publicclassDecoratorTest{publicstaticvoidmain(String[]args){//清洁墙壁WallBeautifywallBeautifyClean=newWallBeautifyClean();wallBeautifyClean.operation();System.out.println("------------");//刮腻子WallBeautifywallBeautifyPutty=newWallBeautifyPutty(wallBeautifyClean);wallBeautifyPutty.operation();System.out.println("------------");//绘制WallBeautifywallBeautifyPaint=newWallBeautifyPaint(wallBeautifyPutty);wallBeautifyPaint.operation();System.out.println("------------");//WallBeautifywallBeautifyHang=newWallBeautifyHang(wallBeautifyPaint);wallBeautifyHang.operation();System.out.println("------------");//多层嵌套WallBeautifywbh=newWallBeautifyHang(newWallBeautifyPaint(newWallBeautifyPutty(newWallBeautifyClean())));wbh.operation();System.out.println("--------------");}}本教程所有实战源码已上传到本仓库:https://github.com/javastacks...输出结果:开始刷墙--------------开始清墙开始刮腻子---------------开始清墙开始刮腻子开始粉刷----------------开始刷墙,开始刮腻子,开始刷漆,开始挂壁画---------------开始刷墙,开始刮腻子,开始刷漆,开始挂壁画-------------输出正常!可见装饰器模式的使用还是比较简单的。使用装饰器模式可以实现不同的装饰效果,可以在不改变原有代码的情况下满足不同客户的需求。还是很不错的后续《设计模式》系列文章在公众号Java技术栈陆续更新中,请继续关注!装饰器模式在JDK中的应用知道了装饰器模式的使用方法之后,我们来看看JDK在哪些地方使用了装饰器模式。1、IO流最经典的装饰器模式应用就是JDK中的IO流(InputStream/OutputStream)。常用的InputStream类结构如下:InputStream和FileInputStream是基本的组件接口和实现。FilterInputStream是一个装饰器角色,实现了组件接口,持有实例引用:BufferedInputStream和DataInputStream是FilterInputStream的不同装饰实现。OutputStream也是同样的原理。2、同步集合应该简单的为非线程安全的集合(如List、Set)提供线程安全的函数,也可以使用装饰器模式轻松实现。再看synchronized集合工具类方法:java.util.Collections#synchronizedList(List)java.util.Collections#synchronizedSet(Set)都是SynchronizedCollection的装饰器实现类:SynchronizedCollection是装饰器角色:SynchronizedCollection实现了集合组件interface并持有集合实例引用,而Collection(List)和ArrayList是基本的组件接口和实现。总结本文介绍了装饰器模式的基本概念,也做了一个基本的实践,并给出了JDK中装饰器模式的两个例子。相信大家对装饰者模式以及如何应用到项目中都有基本的了解,每个人都应该有分数吧?当然,设计模式只是给大家一个设计参考,不能盲目使用,否则会适得其反。顺便问一下,你是如何在你的项目中应用装饰器模式的?欢迎留言分享案例!本教程所有实战源码已经上传到本仓库:https://github.com/javastacks...好了,今天的分享就到这里。后面会更新其他设计模式的实战文章,公众号Java技术栈第一时间推送。Java技术栈《设计模式》系列文章陆续更新中,敬请持续关注!最后,如果觉得我的文章对你有用,动动你的小手,送给正在看的人,转发吧,原创不易,楼主需要你的鼓励。版权声明:本文为公众号《Java技术栈》原创。转载、引用本文内容请注明出处。抄袭、洗稿均属侵权投诉,后果自负,并保留追究法律责任的权利。近期热点文章推荐:1.1000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.20w程序员红包封面,快拿。..5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!