装饰者模式

装饰者模式有一个设计非常巧妙的结构,可以为对象动态添加功能。在基本的设计原则中,有一个重要的原则叫做合成/聚合复用原则。根据该原则的思想,代码复用应该尽可能使用委托,而不是继承。
因为继承是一种紧密耦合,任何父类的改动都会影响其子类,不利于系统维护。而委托则是松散耦合,只要接口不变,委托类的变动并不会影响其上层维护对象。

装饰者模式充分运用了这种思想,通过委托机制,复用系统的各个组件,在运行时,将这些组件功能进行叠加,从而构造出一个“超级对象”,使其拥有所有这些组件的功能。
而各个子功能模块,被很好的维护在各个组件的相关类中,拥有简洁的系统结构。

下面以一个例子来说明。
IPacketCretor即装饰者接口,用于处理具体的内容。PacketBodyCreator是具体的组件,用于构造要发布的信息的核心内容,但是它不负责将其构造成一个格式工整、可直接发布的数据格式。
PacketHTTPHeaderCreator负责给具体的内容加上HTTP头部,PacketHTMLHeaderCreator负责将给定的内容格式化成HTML文本。3个功能组件相互独立且分离,便于系统维护。

IPacketCreator

/**
 * Created by j.tommy on 2017/9/14.
 */
public interface IPacketCreator {
    public String handleContent(); // 用于处理具体内容
}

PacketBodyCreator

/**
 * Created by j.tommy on 2017/9/14.
 */
public class PacketBodyCreator implements IPacketCreator {
    @Override
    public String handleContent() {
        return "Content of packet.";
    }
}

PacketDecorator

/**
 * Created by j.tommy on 2017/9/14.
 */
public abstract class PacketDecorator implements IPacketCreator {
    IPacketCreator ipc;
    public PacketDecorator(IPacketCreator ipc) {
        this.ipc = ipc;
    }
}

PacketHTMLHeaderCreator

/**
 * Created by j.tommy on 2017/9/14.
 */
public class PacketHTMLHeaderCreator extends PacketDecorator {
    public PacketHTMLHeaderCreator(IPacketCreator ipc) {
        super(ipc);
    }
    @Override
    public String handleContent() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("<html>");
        buffer.append("<body>");
        buffer.append(ipc.handleContent());
        buffer.append("</body>");
        buffer.append("</html>");
        return buffer.toString();
    }
}

PacketHTTPHeaderCreator

/**
 * Created by j.tommy on 2017/9/14.
 */
public class PacketHTTPHeaderCreator extends PacketDecorator {
    public PacketHTTPHeaderCreator(IPacketCreator ipc) {
        super(ipc);
    }
    @Override
    public String handleContent() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("Cache-Control:no-cache\n");
        buffer.append(ipc.handleContent());
        return buffer.toString();
    }
}

测试类Main

/**
 * Created by j.tommy on 2017/9/14.
 */
public class Main {
    public static void main(String[] args) {
        IPacketCreator ipc = new PacketHTTPHeaderCreator(new PacketHTMLHeaderCreator(new PacketBodyCreator()));
        System.out.println(ipc.handleContent());
    }
}

输出:

对于装饰者模式,另一个值得关注的地方是它的使用方法。在本例中,通过层层构造和组装装饰者与被装饰者到一个对象中,使其有机的结合在一起工作。

在本例中,共生成3个对象实例,PacketBodyCreator作为核心组件被首先 构造,其次是PacketHTMLHeaderCreator(将内容包装成HTML格式),最后是PacketHTTPHeaderCreator(添加HTTP头)。

在JDK的实现中,也有装饰者模式的实现。一个典型的例子就是OutputStream和InputStream的实现。以OutputStream为例,OutputStream提供的功能较弱,通过各种装饰器的增强,OutputStream可以被赋予强大的功能。

生成一个有缓冲功能的流对象

DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("d:/test.txt")));

生成一个没有缓冲功能的流对象

DataOutputStream dos = new DataOutputStream(new FileOutputStream("d:/test.txt"));

第1种加入了性能组件BufferedOutputStream,第二种则没有。因此第1种拥有更好的性能。

在BufferedOutputStream中,并不是每次调用write方法都会向磁盘写入数据,而是将数据写入缓冲,只有缓冲满的时候才会调用FileOutputStream的write方法向磁盘写入,以此实现功能组件与性能组件的完美分离。

参考:《《Java程序性能优化-让你的Java程序更快、更稳定》(葛一宁等编著)》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值