共计 4608 个字符,预计需要花费 12 分钟才能阅读完成。
背景
你还在写满屏的爆炸类吗?
就是不管三七二十一,把所有代码写在一个类外面,这样代码不优雅不说,如果改变波及到老代码,可能还会影响线上的零碎稳定性。
其实,很多状况,咱们奇妙地利用设计模式就能解决很多潜在的零碎问题,明天栈长就教大家应用装璜器模式,在不改变老代码的前提下扩大性能,岂但能晋升代码优雅性,还能不影响现有的性能,谁用谁晓得,真香!!
什么是装璜器模式?
装璜器模式,从字面上了解,顾名思义,就是一种装璜模式,它能够在不改变原有代码的状况下,对现有的对象、行为进行新的档次的包装、装璜,加强原有的基本功能以提供更丰盛的能力。
举个简略的装修的小例子:
清理 > 刮腻子 > 涂油漆 > 挂壁画
也能够是:
清理 > 刮腻子 > 贴大理石 > 挂电视
或者能够是:
清理 > 刮腻子 > 贴墙纸
这是一步步的简略装修墙面过程(哈哈,大略如此,我不是业余的),这就是装璜器模式,装璜的每个步骤互不干涉,但前面的步骤须要依赖前一个步骤的实现,前面的步骤能够一直在前一个的装璜根底上进行减少。
装璜器模式结构图如下:
装璜器模式类构造如下:
- 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 开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞 + 转发哦!