装饰设计模式
装饰设计模式概述
装饰模式就是使用被装饰类的一个子类的实例,在客户端将这个子类的实例交给装饰类。是继承的替代方案
优点
使用装饰模式,可以提供比继承更灵活的扩展对象的功能,它可以动态的添加对象的功能,并且可以随意的组合这些功能
缺点
正因为可以随意组合,所以就可能出现一些不合理的逻辑
装饰设计模式,就是继承的替代方案。
例子:
手机的例子:(装饰设计模式)
现在用个电脑类来写代码例子:
1、现在有个电脑的规则接口:
/**
* 这是电脑类的规则接口
*
* @author LZL
*
*/
public interface Computer {
// 电脑用来办公
public void office();
}
2、制作了一台ThinkPad电脑:(实现电脑规则接口的实现类)
/**
*
* 实现了电脑规则的接口
*
* @author LZL
*
*/ public class ThinkPad implements Computer { public void office() {
System.out.println("ThinkPad可以办公");
} }
3、我想用这台电脑在办公后编程,那么我就需要一个总的装饰类,以及一个编程的装饰类
总的装饰类:(由于是对电脑进行装饰,所以要实现电脑规则的接口)
/**
* 这是对电脑进行装饰的装饰类
*
* @author LZL
*
*/
public class CPDecorate implements Computer { // 接收一个电脑类
private Computer cp; public CPDecorate(Computer cp) {
this.cp = cp;
} // 实现电脑类的方法
public void office() {
this.cp.office();
} }
编程的装饰类:(对电脑增加编程功能的装饰类,得继承电脑的装饰类来实现)
/**
* 这是对电脑增加编程功能的装饰类,得继承电脑的装饰类来实现
*
* @author LZL
*
*/ public class ProGramme extends CPDecorate { public ProGramme(Computer cp) {
super(cp);
} // 调用电脑的办公功能
public void office() { super.office();
System.out.println("还可以编程");
} }
同理,我想要在办公前听下音乐,就要一个音乐的装饰类:
public class Music extends CPDecorate { public Music(Computer cp) {
super(cp);
} public void office() {
System.out.println("听音乐");
super.office();
}
}
最后,我运行这台电脑:
public class ComputerDemo { public static void main(String[] args) { // 创建电脑对象
Computer cp = new ThinkPad();
cp.office();
System.out.println("--------"); // 我要办公后来编程,那么就需要一个装饰类来实现
// 创建装饰后的电脑对象
CPDecorate cpd = new ProGramme(cp);
cpd.office();
System.out.println("------"); // 我想在办公前听音乐,再来个装饰类
cpd = new Music(cp);
cpd.office();
System.out.println("------"); // 我想在办公前听音乐,办公后编程
cpd = new Music(new ProGramme(cp));
cpd.office();
} }
其实,我们之前在IO流就已经用过了装饰设计模式。
理解下面:
比如:
输入字节流转换成输入字符流:(一次性只能读取一个字节 → 一次性可以读取一个字符)
InputStreamReader isr = new InputStreamReader(is);
然后再转换成高效输入字符流:(一次性只能读取一个字符 → 一次性可以读取一行字符)
BufferedReader br = new BufferedReader(isr);
上面两个合起来: 输入字节流转换成高校输入字符流(一次性只能读取一个字节 → 一次性可以读取一行字符)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
还有,输出字节流转换成高效输出字符流
BufferedWriter bw = new BufferedWriter((newOutputStreamWriter(
System.out)));