装饰者设计模式
提到装饰者设计模式,使用过JAVA IO编程的人都应该熟悉,JAVA IO包就是使用装饰器模式设计的,比如,为了
快速的从inputStream流中读取数据,我们使用BufferedInputStream装饰该流,被它装饰的流增加了缓冲数据的功能。装饰器模式可以让我们在动态的增强对象的功能,从而不影响程序的使用。当然,让我们在动态的增强对象的功能的方法不止这一种,还有一种是动态代理,另外就是我们所熟悉的继承机制了,有时候采用继承会有很大的缺点,最大的弊端就是,可能会产生“类爆炸”,所以我们还是采用装饰者设计模式比较好。
我们来看一下装饰者模式的官方定义:
装饰者模式动态的将职责附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
下面举个例子
以前的手机最重要的功能就是打电话了,但是随着发展,我们的手机(Phone)不仅可以打电话了,而且又可以播放音乐(MusicPhone),看视频了(VideoPhone)又随着发展,手机增加可以上网的功(MusicAndInternetPhone)。。不断的随着发展,手机变得越来越智能,手机的功能是在是太多了,我们想象一下,如果我们按照继承的思想去解决这个问题,那么子类就太多了,也就是我们所说的类爆炸!现在让我们看看装饰者设计模式是怎么做的!
在这个问题中,要用装饰来实现,包含下面四个部分
a、被装饰的抽象事物------手机接口
b、具体的手机事物-------是实现手机接口的具体类
c、对手机进行装饰的抽象类
d、对手机进行具体装饰的类
其体系结构是:
Phone
|---PhoneDecorate
|--MusicPhoneDecorete
|--VideoPhoneDecorete
|---PhoneImpl
现在看一看具体的实现代码
public interface Phone {
/**
* 打电话
*/
public abstract void call();
}
public class PhoneImpl implements Phone {
@Override
public void call() {
System.out.println("手机可以打电话");
}
}
/**
* 手机装饰者
*
*/
public abstract class PhoneDecorate implements Phone{
private Phone phone;
public PhoneDecorate(Phone phone) {
super();
this.phone = phone;
}
@Override
public void call() {
this.phone.call();
}
}
/**
*
*音乐手机装饰者
*
*/
public class MusicPhoneDecorete extends PhoneDecorate {
public MusicPhoneDecorete(Phone phone) {
super(phone);
}
@Override
public void call() {
super.call();
System.out.println("手机还可以播放音乐");
}
}
/**
*
*视频手机装饰者
*
*/
public class VideoPhoneDecorete extends PhoneDecorate {
public VideoPhoneDecorete(Phone phone) {
super(phone);
}
@Override
public void call() {
super.call();
System.out.println("手机还可以看视频");
}
}
/**
*
* 测试类
*
*/
public class Test {
public static void main(String[] args) {
Phone phone=new PhoneImpl();
//音乐装饰类
PhoneDecorate pdm=new MusicPhoneDecorete(phone);
pdm.call();//输出:手机可以打电话,手机还可以播放音乐
PhoneDecorate pdv=new VideoPhoneDecorete(phone);
pdv.call();//手机可以打电话,手机还可以看视频
PhoneDecorate pdmv=new VideoPhoneDecorete(new MusicPhoneDecorete(phone));
pdmv.call();//手机可以打电话,手机还可以播放音乐,手机还可以看视频
}
}
这就是装饰者的实现了,现在我们来一下装饰者模式的类图。。。。
再让我们看看IO中的装饰者的例子
FileInputStream是被装饰的组件。javaIO程序提供就几个组件,包括了FileInputStream,StringBufferInputStream,ByteArrayInputStream...等等,这些类都提供了最基本的字节读取的功能BufferedInputStream及LineNumberInputStream都扩展自FilterInputStream,而FilterInputStream是一个抽象的基类,LineNumberInputStream也是一个具体的装饰者,它加上了计算行号的功能。好啦这就是装饰者设计模式。。。