装饰者模式
装饰者模式-wrap
HeadFirst中的定义:动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案
装饰者模式的组成
装饰者模式由装饰者和被装饰者组成,也可以表述为主体(被装饰者)和附体(装饰者)(自己的理解),下面以生活中的例子来描述一下装饰者与被装饰者。
例如我们每天出去逛街的时候,都会为自己打扮一番,穿上一些漂亮的衣服,帽子,鞋子,首饰等等。这个例子中的人就是主体(被装饰者),漂亮的衣服,帽子,鞋子,首饰等就是附体(装饰者),装饰者附加在主体上面,可以给主体做一些美化目的(或者说增加一些新的样式)。
HeadFirst中的咖啡店的例子
我们去咖啡店点咖啡的时候,每个人可能会根据自己的喜好加一些特殊材料。比如,咖啡加糖加奶,咖啡不加糖不加奶,咖啡加糖不加奶等等。这个例子中的咖啡就是主体,糖和奶是附体。
主体和附体的特点
- 主体和附体有相同的接口或超类
- 附体中有主体的引用。
- 附体中实现这个共同的接口时,会调用主体的实现,并加上自己特有的功能。
废话不多说我们先看下第一个例子的代码
/**
* 被装饰者(主体)人
*/
public class Person implements Show {
@Override
public String show() {
return "人";
}
}
/**
* 装饰者-眼镜
*/
public class Glasses implements Show {
//被装饰者的引用
private Show show;
public Glasses(Show show) {
super();
this.show = show;
}
@Override
//附体中实现接口时,会调用主体的实现show.show(),并加上自己特有的功能(带着眼镜的)。
public String show() {
return "带着眼镜的"+show.show();
}
}
/**
*
* 主体和附体共同的接口
*/
public interface Show {
public String show();
}
/**
* 装饰者-衣服
*/
public class Clothes implements Show {
//主体
private Show show;
public Clothes(Show show) {
super();
this.show = show;
}
@Override
public String show() {
return "穿着漂亮衣服的"+show.show();
}
}
/**
* 装饰者-鞋子
*/
public class Shoe implements Show {
//主体
private Show show;
public Shoe(Show show) {
super();
this.show = show;
}
@Override
public String show() {
return "穿着鞋子的"+show.show();
}
}
1.主体人和附体鞋子有共同的接口show
2.附体中有被装饰者的引用private Show show;
3.附体的接口实现中增加了自己的功能,如“穿着鞋子的”
public static void main(String[] args) {
Show show = new Person();
System.out.println(show.show());;
//给人穿个衣服
show = new Clothes(show);
System.out.println(show.show());
//给人穿个鞋子
show = new Shoe(show);
System.out.println(show.show());
}
执行结果:
人
穿着漂亮衣服的人
穿着鞋子的穿着漂亮衣服的人
装饰者模式在JDK中的应用
InputStream、FilterInputStream是主体和附体共同的接口
FileInputStream、StringBufferInputStream、ByteArrayInputStream 是主体类(被装饰者)
PushBackInputStream、BufferedInputStream、DataInputStream、LineNumberInputStream是装饰者实现。
java I/O中引出装饰者模式的一个缺点:利用装饰者模式,长造成设计中有大量的小类,数量太多,可能会造成API使用者的困扰。