装饰者模式的一个典型案例就是对输出结果进行增强,其核心思想在于:无需将所有的逻辑,即核心内容构建、html文本构造和html头生成等3个功能模块粘合在一起实现。通过装饰者模式,可以将它们分解为3个几乎完全独立的组件,并在使用时灵活地进行装配。
以下图是案例结构:
代码案例如下:
/** * 装饰接口,用于处理内容 * @author txy * */
public interface IPacketCreator {
public String handleContent();
}
/**
* 具体的组件上,功能是构造要发布 信息的核心内容,但是它不负责将期构造成一个格式工整、可直接发布的数据格式
* @author txy
*
*/
public class PacketBodyCreator implements IPacketCreator {
@Override
public String handleContent() {
// TODO Auto-generated method stub
return "Content of Packet";
}
}
/**
* 核心维护组件component对象,它负责告知其子类,其核心业务逻辑应该全权委托componment完成,自己仅仅是做增强处理
* @author txy
*温馨提示:抽象类实现接口,可不实现接口中的方法
*/
public abstract class PacketDecorator implements IPacketCreator{
IPacketCreator component;
public PacketDecorator (IPacketCreator c){
component = c;
}
}
/**
* 是具体的装饰器,它负责对核心发布 的内容进行html格式化操作。
* 需要特别注意的是,它委托了具体组件componment进行核心业务处理
* @author txy
*
*/
public class PacketHTMLHeaderCreator extends PacketDecorator{
public PacketHTMLHeaderCreator(IPacketCreator c) {
super(c);
// TODO Auto-generated constructor stub
}
@Override
public String handleContent() {
StringBuffer sb = new StringBuffer();
sb.append("<html>");
sb.append("<body>");
sb.append(component.handleContent());
sb.append("</body>");
sb.append("</html>\n");
return sb.toString();
}
}
/**
* 完成http头部的处理,其余业务处理依然交由内部的component完成
* @author txy
*
*/
public class PacketHTTPHeaderCreator extends PacketDecorator {
public PacketHTTPHeaderCreator(IPacketCreator c) {
super(c);
// TODO Auto-generated constructor stub
}
@Override
public String handleContent() {
StringBuffer sb = new StringBuffer();
sb.append("Cache-Control:no-cache\n");
sb.append("Date:Mon,31Dec20160324:13:13GMT\n");
sb.append(component.handleContent());
return sb.toString();
}
}
/**
* 对于装饰者模式,另一个值得关注的地方是它的使用方法。
* 在本例中,通过层层构造和组装这些装饰者和被装饰者到一个对象中,使其有机地结合在一起工作。
* @author txy
*
*/
public class Main {
public static void main(String args[]){
IPacketCreator pc = new PacketHTTPHeaderCreator(new PacketHTMLHeaderCreator(new PacketBodyCreator()));
System.out.println(pc.handleContent());
}
}
最后执行结果如下:
在jdk的实现中,下面是一个典型的案例
public static void main1() throws IOException{
DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("C:\\a.txt")));
DataOutputStream dout1 = new DataOutputStream(new FileOutputStream("C:\\a.txt"));
long begin = System.currentTimeMillis();
for(int i= 0;i<10000;i++){
dout.writeLong(i);
}
System.out.println("speed:"+(System.currentTimeMillis()-begin));
}
}
以上代码显示了FileOutputStream的典型应用 。dout和dout1是两种建立OutputStream的方法,第一种加入了性能组件BufferedOutputStream,第二种则没有。因此,第一种方法产生的OutputStream拥有更好的IO性能。
总结:
JDK中OutputStream和InputStream类族的实现是装饰者模式的典型应用。通过嵌套的方式不断地将对象聚合起来,最终形成一个超级对象,并使之拥有所有的相关子对象的功能。