HeadFirst 设计模式笔记(三)—— decorator

来源:互联网 发布:java ide 编辑:程序博客网 时间:2024/05/17 00:09
装饰者模式:使用对象组合的方式在运行时给对象赋予新的功能(装饰),而不是滥用继承。

举个例子就清晰了:java.io这个包中就应用了这一模式FilterInputStream是一个装饰者类,它和它的子类可以对InputStream的其他子类进行装饰。

class java.io.InputStream
  • class java.io.ByteArrayInputStream
  • class java.io.FileInputStream
  • class java.io.FilterInputStream
    • class java.io.BufferedInputStream
    • class java.io.DataInputStream (implements java.io.DataInput)
    • class java.io.LineNumberInputStream
    • class java.io.PushbackInputStream
  • class java.io.ObjectInputStream (implements java.io.ObjectInput, java.io.ObjectStreamConstants)
  • class java.io.PipedInputStream
  • class java.io.SequenceInputStream
看看这行语句:new LineNumberInputStream(new BufferedInputSream(new FileInputStream(...)));

这就是装饰者模式的典型用法,通过用一个新的对象包装原有对象从而获得新的功能。通过这种方式我们不必更改FileInputStream这个类就可以获得新的功能了。

更重要的一点是,由于装饰者和被装饰者都继承自同一个超类,所以被装饰过的对象并不会因此改变类型而影响使用。换句话说,只要我们的方法以InputStream为参数,假设以前我们的实参为FileInputStream,而现在我们使用装饰过以后的FileInputStream(例如BufferedInputStream)做实参,使得我们的方法拥有了新的功能(因为BufferedInpustStream覆盖了FileInputStream中的一些方法,比如read),而不需修改代码。

我们把BufferedInpustStream抽取成一个装饰类以后可以用它来装饰多个InputStream家族中的类,这样会更灵活。相反,如果当我们希望FileInputStream有Buffer功能时就建立一个新类叫BufferedFileInputStream的话… 这种思路将产生很多类,很多重复代码,而且很不灵活。

装饰者模式:动态地将责任附加到对象上,想要扩展功能,装饰者是有别于继承的另一种选择。