【趣味设计模式系列】之【装饰器模式】
1. 简介
装饰器模式(Decorator Pattern):动态地给一个对象添加职责,就增加功能来说,装饰器比生成子类更灵活。
2. 示例
水果店需要给网上客户发货,除了包装之外,需要对特定水果包装加额外装饰,比如加防伪标志、加固、加急等额外功能,但在外部看来还是打包组件。
水果包装接口类Bag,接口方法pack,完成水果打包。
苹果、橘子、香蕉各自实现包装接口,用自己的特定的外包装。
装饰器类BagDecorator,实现包装类Bag接口,同时拥有包装接口的引用,为了组装更多具体装饰器加入进来,增加包装类的装饰功能。
防伪装饰器CheckedBagDecorator,继承BagDecorator类,并增加自己的防伪标识方法checked。
加固装饰器ReinforceBagDecorator,继承BagDecorator类,并增加自己的加固方法reinforce。
加急装饰器SpeedBagDecorator,继承BagDecorator类,并增加自己的加急方法speedy。
客户端类
结果
从上述例子可以看出,装饰器的好处,不仅可以对具体的水果包装类进行装饰,多个装饰器还可以嵌套装饰
,非常灵活,这也是为什么,装饰器中需要引用Bag类,就是方便嵌套,因为每个具体的装饰器,本身也是Bag的子类。
3. 源码分析
Java IO类库非常庞大,从大类分,如果从按流的方向来分的话,分为输入流InputStream,输出流OutputStream,如果按照读取的方式分的话,分为字节流与字符流,具体如下图
针对不同的读取和写入场景,Java IO 又在这四个父类基础之上,扩展出了很多子类,如下图
OutputStream 是一个抽象类,FileOutputStream 是专门用来写文件流的子类,FilterOutputStream很特殊,它实现了OutputStream,同时持有OutputStream的引用,部分源码如下图:
所以FilterOutputStream在设计的时候本质就是一个装饰器,其子类BufferedOutputStream,DataOutputStream,PrintStream都是具体的装饰器,实现额外的功能。
同样FilterInputStream、InputStreamReader、OutputStreamWriter都是装饰器类,其子类充当具体装饰的功能。
在平时写代码的时候都有如下几行嵌套的写法:
本质上,OutputStream的实现类可以与具体装饰器实现相互嵌套,具体的装饰器之间也可以相互嵌套,非常灵活,避免了独立为每个类创建子类而产生累爆炸的不合理设计。
4. 总结
4.1 优点
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
- 处理可以撤销的职责。
- 扩展子类灵活,避免产生累爆炸。
4.2 缺点
- 如果最里面的装饰器出错,需要从外面一层一层往里面去查看,多层嵌套导致增加复杂性。
__EOF__

本文链接:https://www.cnblogs.com/father-of-little-pig/p/13622216.html
关于博主:不要为了技术而技术,总结分享技术,感恩点滴生活!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY