背景
你还在写满屏的爆炸类吗?
就是不管三七二十一,把所有代码写在一个类外面,这样代码不优雅不说,如果改变波及到老代码,可能还会影响线上的零碎稳定性。
其实,很多状况,咱们奇妙地利用设计模式就能解决很多潜在的零碎问题,明天栈长就教大家应用装璜器模式,在不改变老代码的前提下扩大性能,岂但能晋升代码优雅性,还能不影响现有的性能,谁用谁晓得,真香!!
什么是装璜器模式?
装璜器模式,从字面上了解,顾名思义,就是一种装璜模式,它能够在不改变原有代码的状况下,对现有的对象、行为进行新的档次的包装、装璜,加强原有的基本功能以提供更丰盛的能力。
举个简略的装修的小例子:
清理 > 刮腻子 > 涂油漆 > 挂壁画
也能够是:
清理 > 刮腻子 > 贴大理石 > 挂电视
或者能够是:
清理 > 刮腻子 > 贴墙纸
这是一步步的简略装修墙面过程(哈哈,大略如此,我不是业余的),这就是装璜器模式,装璜的每个步骤互不干涉,但前面的步骤须要依赖前一个步骤的实现,前面的步骤能够一直在前一个的装璜根底上进行减少。
装璜器模式结构图如下:
装璜器模式类构造如下:
- Component:组件接口类,定义被装璜类的基本功能
- ConcreteComponent: 组件接口的根本实现类
- Decorator:装璜器角色类, 实现并持有一个 Component 对象实例
- ConcreteDecorator:装璜器的实现类
装璜器模式的长处:
1、不改变原有代码,动静减少性能;
2、对象之间不会相互依赖,松耦合,够优雅;
3、合乎开闭准则,扩展性好、便于保护;
装璜器模式的毛病:
1、装璜环节如果很多的话,会造成装璜器类收缩;
2、装璜器层层嵌套比较复杂,使用者必须分明所有的装璜器类及其用处;
装璜器模式实战
咱们把下面的装修的案例用装璜器模式实现一下。
组件接口类:
/** * 墙面装修接口 * @author: 栈长 * @from: 公众号Java技术栈 */public interface WallBeautify { /** * 装修操作 * @author: 栈长 * @from: 公众号Java技术栈 */ void operation();}
组件接口的根本实现类:
/** * 墙面装修根本实现(清理墙面) * @author: 栈长 * @from: 公众号Java技术栈 */public class WallBeautifyClean implements WallBeautify { @Override public void operation() { System.out.println("开始清理墙面"); }}
装璜器角色类:
这是一个抽象类,实现并持有一个 Component 对象实例,这里应用的是聚合,而不是继承,这也是装璜器模式的要点所在。
/** * 墙面装修装璜器角色 * @author: 栈长 * @from: 公众号Java技术栈 */public abstract class WallBeautifyDecorator implements WallBeautify { /** * 持有一个 Component 对象实例 * @author: 栈长 * @from: 公众号Java技术栈 */ private WallBeautify wallBeautify; public WallBeautifyDecorator(WallBeautify wallBeautify) { this.wallBeautify = wallBeautify; } @Override public void operation() { wallBeautify.operation(); decoration(); } /** * 装璜器实现类自定义实现办法 * @author: 栈长 * @from: 公众号Java技术栈 */ public abstract void decoration();}
覆写原操作方法,在原操作之后再进行装璜,所以须要提供一个形象的 decoration 办法供不同的装璜器的实现类去实现。
装璜器的实现类:
这里定义了 3 个装修过程:
刮腻子 > 涂油漆 > 挂壁画
所以各自去继承 装璜器角色类 并实现其装璜办法:
/** * 墙面装修装璜器角色实现(刮腻子) * @author: 栈长 * @from: 公众号Java技术栈 */public class WallBeautifyPutty extends WallBeautifyDecorator { public WallBeautifyPutty(WallBeautify wallBeautify) { super(wallBeautify); } @Override public void decoration() { System.out.println("开始刮腻子"); }}
/** * 墙面装修装璜器角色实现(涂油漆) * @author: 栈长 * @from: 公众号Java技术栈 */public class WallBeautifyPaint extends WallBeautifyDecorator { public WallBeautifyPaint(WallBeautify wallBeautify) { super(wallBeautify); } @Override public void decoration() { System.out.println("开始涂油漆"); }}
/** * 墙面装修装璜器角色实现(挂壁画) * @author: 栈长 * @from: 公众号Java技术栈 */public class WallBeautifyHang extends WallBeautifyDecorator { public WallBeautifyHang(WallBeautify wallBeautify) { super(wallBeautify); } @Override public void decoration() { System.out.println("开始挂壁画"); }}
测试一下:
/** * 装璜器模式测试类 * @author: 栈长 * @from: 公众号Java技术栈 */public class DecoratorTest { public static void main(String[] args) { // 清理墙面 WallBeautify wallBeautifyClean = new WallBeautifyClean(); wallBeautifyClean.operation(); System.out.println("--------------"); // 刮腻子 WallBeautify wallBeautifyPutty = new WallBeautifyPutty(wallBeautifyClean); wallBeautifyPutty.operation(); System.out.println("--------------"); // 涂油漆 WallBeautify wallBeautifyPaint = new WallBeautifyPaint(wallBeautifyPutty); wallBeautifyPaint.operation(); System.out.println("--------------"); // 挂壁画 WallBeautify wallBeautifyHang = new WallBeautifyHang(wallBeautifyPaint); wallBeautifyHang.operation(); System.out.println("--------------"); // 多层嵌套 WallBeautify wbh = new WallBeautifyHang(new WallBeautifyPaint( new WallBeautifyPutty(new WallBeautifyClean()))); 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)简略提供线程平安的性能,应用装璜器模式也能轻松实现。
来看同步汇合工具类办法:
java.util.Collections#synchronizedList(List)
java.util.Collections#synchronizedSet(Set)
它们都是 SynchronizedCollection 的装璜器实现类:
SynchronizedCollection 是装璜器角色:
SynchronizedCollection 实现了汇合组件接口并持有汇合实例援用,而 Collection(List) 和 ArrayList 是根本的组件接口和实现。
总结
本文介绍了装璜器模式的基本概念,也做了一个根本实战,并且举了两个 JDK 中的装璜器模式的例子,置信大家对装璜器模式有了一个根本意识了,怎么使用到我的项目中,大家应该有谱了吧?
当然,设计模式只是给大家一个设计的参考,并不能自觉使用,否则事与愿违。话说,你是怎么在我的项目中利用装璜器模式的呢?欢送留言分享案例!
本节教程所有实战源码已上传到这个仓库:
https://github.com/javastacks...
好了,明天的分享就到这里了,前面栈长我会更新其余设计模式的实战文章,公众号Java技术栈第一工夫推送。Java技术栈《设计模式》系列文章陆续更新中,请大家继续关注哦!
最初,感觉我的文章对你用播种的话,动动小手,给个在看、转发,原创不易,栈长须要你的激励。
版权申明: 本文系公众号 "Java技术栈" 原创,转载、援用本文内容请注明出处,剽窃、洗稿一律投诉侵权,后果自负,并保留追究其法律责任的权力。
近期热文举荐:
1.1,000+ 道 Java面试题及答案整顿(2022最新版)
2.劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4.20w 程序员红包封面,快快支付。。。
5.《Java开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞+转发哦!