装饰者模式是为了给已有的对象增加一些逻辑,但是不改变已有对象的代码,下面是类图:
从上图可以看出,装饰者 Decorator
与需要被装饰的对象 ContcreteComponent
实现了相同的接口。具体怎么装饰则由 Decorator
的子类 ConcreteDecorator
决定。
Java 中使用装饰者模式的一个典型的例子是 I/O 对象的创建,比如创建一个 BufferedInputStream
时:
InputStream in = ...
InputStream input = new BufferedInputStream(in);
BufferedInputStream
继承于 FilterInputStream
,这个 FilterInputStream
相当于装饰者模式中的 Decorator
,它继承了 InputStream
接口。BufferedInputStream
则是一个具体的装饰类,其它还有 DataInputStream
以及 ByteArrayInputStream
等。而传给 BufferedInputstream
的对象 in
则是需要被装饰者。装饰者对被装饰者进行了功能的扩展,但是又不需要修改被装饰者的相应代码,符合“开闭原则”,即对于修改是封闭的,对于扩展则是开放的。
如果是为了给某个类提供更多的功能,继承是一种方案。但是,如果我们的功能有很多种组合,那么为每种组合编写一个继承的类可能需要创建太多的子类。而装饰者模式则可以解决这个问题,只需要为每个功能编写一个装饰类,在运行时组合不同的对象即可实现所需的功能组合。