【设计模式】结构型设计模式之 从IO流设计思想来看装饰器模式
创作时间:
作者:
@小白创作中心
【设计模式】结构型设计模式之 从IO流设计思想来看装饰器模式
引用
CSDN
1.
https://blog.csdn.net/weixin_40979518/article/details/139553486
介绍
装饰器模式也称为包装模式(Wrapper Pattern) 是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。
装饰器模式的核心是功能扩展,使用装饰器模式可以透明且动态地扩展类的功能。
装饰器模式代码举例
实现逻辑
- 装饰器类和原始类实现共同的父类,下方案例中的 Coffe
- 装饰器类,组合原始类的对象作为目标对象
- 装饰器类重写需要装饰的方法,并且重写的内容中可以调用原始类的对象方法。
- 通过中间层的装饰器基类,避免实现每个共同父类的方法
代码
//装饰器和目标类基础接口
public interface Coffee {
String getDescription();
double getCost();
}
//具体的咖啡,什么都不加
public class SimpleCoffee implements Coffee {
@Override
public String getDescription() {
return "Simple Coffee";
}
@Override
public double getCost() {
return 1.0;
}
}
//装饰器基类,为了避免每个装饰器都要手动重新实现共同父类的接口,即使该装饰器不需要装饰对应方法
public abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
@Override
public abstract String getDescription();
@Override
public double getCost() {
return decoratedCoffee.getCost();
}
}
//摩卡咖啡装饰器,增加风味描述、增加价格
public class MochaDecorator extends CoffeeDecorator {
public MochaDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription() + ", Mocha";
}
@Override
public double getCost() {
return super.getCost() + 0.5;
}
}
//奶油装饰器,增加奶油、增加价格
public class WhipDecorator extends CoffeeDecorator {
public WhipDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription() + ", Whip";
}
@Override
public double getCost() {
return super.getCost() + 0.3;
}
}
//测试类
public class Main {
public static void main(String[] args) {
// 创建一杯简单的咖啡
Coffee simpleCoffee = new SimpleCoffee();
// 添加摩卡装饰
Coffee mochaCoffee = new MochaDecorator(simpleCoffee);
// 再添加奶泡装饰
Coffee finalCoffee = new WhipDecorator(mochaCoffee);
System.out.println(finalCoffee.getDescription() + " costs $" + finalCoffee.getCost());
}
}
Simple Coffee, Mocha, Whip costs $1.8
IO 类库的装饰器模式
为什么没有 BufferdFileInputStream
在 JAVA 的 IO 类库中,例如如果让 FileInputStream 支持 BufferdInputStream,需要让 需要间接的将 FileInputStream 传递给 BufferdInputStream。为什么 Java 不直接支持BufferdFileInputStream 呢。
InputStream in = new FileInputStream("");
InputStream bin = new BufferedInputStream(in);
为什么不基于继承实现 BufferedFileInputStream
- 如果 InputStream 类只有一个子类 FileInputStream 那么再在 FileInputStream 下面实现一个BufferedInputStream 也没有什么问题
- 问题在于 InputStream 的子类太多了,如果每个子类都单独实现 Buffered 功能和 DataInputStream 的功能那么类的数量将会爆炸性增多。
IO 类库使用装饰模式实现
- 在设计原则中,组合优于继承,针对继承结构过于复杂的问题可以将继承关系转换为组合关系来解决。
- 所以 IO 类库中,对于 BufferedInputStream 没有选择对所有的 InputStream 实现一遍,而是只实现一遍通过组合目标 InputStream 来实现增强功能
- 对于需要实现 Buffered 的功能的 inputStream,只需使用BufferedInputStream 对其进行一次包装即可实现。
- 并且如果想要实现 DataInputStream 的按照数据类型读取,只需要再次添加一层包装即可。
总结&思考
总结
- 装饰器模式可以解决继承关系过于复杂的问题,通过组合关系替代继承关系。
- 装饰器模式主要的作用是给原始类添加增强功能,除此之外装饰器模式还支持嵌套使用,为了满足这个功能装饰器类和原始类都继承自相同的父类或者接口。
- 装饰器模式和静态代理模很相似,都是通过组合来对原始类进行增强,主要区别是代理模式主要对原始类不相关的功能进行增强,但是装饰器模式是对原始类相关功能的增强。
IO 类库的 FilterInputStream 的作用是什么
- 和案例中的装饰类基类作用一样,提供 InputStream 需要实现的方法的实现。方法的具体执行通过委托给组合的 InputStream 对象实现。
- 如果没有 FilterInputStream,那么每个装饰器类,都需要对 InputStream 的方法提供实现,即使是委托给组合的 InputStream 成员对象执行也会很麻烦。
装饰器类和原始类有相同的父类的作用
装饰器类和原始类有相同的父类,例如 InputStream 和 Coffee 可以实现对原始类进行“嵌套”多个装饰器类来进行增强。例如对 FileInputStream 包装 BufferedInputStream 后再包装一层 DataInputStream,这样既实现了缓存读取又实现类按照基本数据类型来读取。
和其他组合代替继承的设计模式(例如代理模式)的区别
代理模式中,代理类附加的是原始类不相关的功能,但是装饰器模式中附加的是与原始类相关的增强功能。
热门推荐
2024年女孩名字汇总雅致时尚 姓名选择指南
为什么相对于唐朝和明朝,北宋宦官最没存在感
秋水切埋技术破解东北水稻秸秆全量还田难题
广州拟放开购房入户,一线城市重启“抢人大战”?
车辆转弯半径应如何准确测量?测量结果对驾驶有何帮助?
长粒米与圆粒米:从性状到营养的全面解析
铝合金封阳台用什么规格?选择合适材料是关键
权谋朝堂小说推荐:20部聚焦官场斗争与权力博弈的经典之作
曲面屏长时间使用对眼睛有何影响?(探究曲面屏的长时间使用对视力的潜在风险)
上市公司报表分析,解析成功的企业财务数据
房屋拆迁中如何维权
呼和浩特,“格局”打开!
一座古城如何“驻颜”?——丽江古城27年保护与发展之路
探索咸宁:你不能错过的十大旅游景点与体验
胃息肉是什么东西
离婚3年的赵丽颖:从“草根打工人”到“资本女王”
🏯 穿越时光的振成楼:土楼中的建筑奇迹
笔记本电脑耗电和发热比较厉害怎么处理
PWM(脉宽调制)技术详解:从基础到应用实践示例
电动汽车电池更换的费用是多少
研究发现:99%的瓶装水存在永久化学物质,茶包会释放大量微/纳米塑料
经典IP延续电影《冰雪女王5:融冰之战》故事情节紧凑
以书为友!培养阅读习惯的一些小技巧经验
细说瓷器常见种类 南北方文化差异一同!
最值得投资的 10 只黄金股票(2025 年 XNUMX 月)
万籁声:25岁的武术大师,为何能成为民国时期的全民偶像?
晚上睡觉穿袜子,引火下行!持续1个冬天,可能会有这3大变化
睡眠时间|过度睡眠恐危害健康!揭秘“睡太多”的6大害处及理想睡眠时间
保护亚洲河流亟须数据共享
被开除军籍有什么影响