最近准备阅读下IO源码,传统的IO中涉及两种设计模式:装饰器模式以及适配器模式。因此在这里记录下的我对装饰器模式的个人理解。java IO流的设计是基于装饰者模式&适配模式,面对IO流庞大的包装类体系,核心是要抓住其功能所对应的装饰类。
装饰器模式又叫包装模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。装饰模式通过创建一个包装对象,也就是装饰,来包裹真实的对象。装饰模式以对客户端透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。装饰模式把客户端的调用委派到被装饰类。装饰模式的关键在于这种扩展是完全透明的。
比如在大话设计模式中有个例子:三明治基本组成是两块面包,只不过加了蔬菜、牛肉等其它配置材料。因此要想获取一块丰富材料的三明治,那么得多次继承或者实现多个接口。下面的案例是github上面关于装饰器模式的一种实现:
/**
*
* @author caozg
* 抽象的巨魔接口,规定了如下的三个功能
* 1 攻击能力
* 2 获取攻击值
* 3 逃跑
*/
public interface Troll {
void attack();
int getAttackPower();
void fleeBattle();
}
下面的代码是对抽象接口的最为基础的原子实现:
/**
*
* @author caozg
* 抽象接口的基本实现----最为原始功能的原子实现
*/
public class SimpleTroll implements Troll {
public void attack() {
System.out.println("巨魔尝试着攻击你");
}
public int getAttackPower() {
return 10;
}
public void fleeBattle() {
System.out.println("巨魔惊恐的尖叫并且逃跑");
}
}
增强后的也就是装饰后的巨魔的实现:
/**
* 装饰器类
* @author gosaint
*
*/
public class ClubbedTroll implements Troll {
private Troll decorated;
public ClubbedTroll(Troll decorated) {
this.decorated = decorated;
}
public void attack() {
decorated.attack();
System.out.println("巨魔挥动大棒向你攻击");
}
public int getAttackPower() {
return decorated.getAttackPower()+10;
}
public void fleeBattle() {
decorated.fleeBattle();
}
}
测试如下:
头脑简单的巨魔
巨魔尝试着攻击你
巨魔惊恐的尖叫并且逃跑
简单巨魔能量 {}.
10
给简单的巨魔添加功能--装饰
巨魔尝试着攻击你
巨魔挥动大棒向你攻击
巨魔惊恐的尖叫并且逃跑
加强后巨魔的能量 {}.
20
总结装饰器模式的写法:
1 定义基础接口,定义相应的基础方法 抽象接口
2 定义接触接口的实现类,最为原始的功能点的实现 原始抽象接口实现类
3 定义装饰器类,用来装饰原始抽象接口实现类,使得功能更为强大
① 实现抽象接口
② 将抽象接口的引用作为成员变量
③ 在自己的构造器中初始化抽象接口引用对象
④ 使用抽象接口引用对象调用需要增强的方法,并且在需要增强的方法中写自己增强的逻辑代码
参考文章:https://www.jianshu.com/p/613ee60e08b4
Java design https://github.com/iluwatar/java-design-patterns/tree/master/decorator