装饰者模式:使用对象组合的方式在运行时给对象赋予新的功能(装饰),而不是滥用继承。
举个例子就清晰了: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的话… 这种思路将产生很多类,很多重复代码,而且很不灵活。
装饰者模式:动态地将责任附加到对象上,想要扩展功能,装饰者是有别于继承的另一种选择。