设计模式思考之 Decorator 模式

231 阅读2分钟

这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战

装饰器时至今日,仍然用的十分广泛。咖啡豆刚从咖啡机里面磨出来的时候,什么都不加就是espresso,加点水冲淡一点就是美式,加点牛奶就是卡布奇诺,再多加点牛奶就是拿铁。咖啡豆里磨出来的永远是又黑又苦的水,我们加不同的东西变成了不同的产品,这就是装饰器模式。加一层包装就可以改头换面变成不同的东西,但本质始终不会改变。

装饰器有什么好处呢?可能不能称之为好处,其实在某些情况是解决方案。比如有些sdk里面的代码或者被标识为final的类,你是无法修改的,但又不满足于其简单的功能,这个时候可以用装饰器来扩充其功能又不用写太多代码。或者在普通场景下,某个类的行数已经很多了,足够复杂了,但又有新需求,不得不做一些新功能,这个时候就可以用装饰器来做。因为装饰类和原来的类是委托关系,是比较弱的关联关系。类图如下:

image.png

在jdk中,装饰器用的非常广泛,比如:


Reader reader = new FileReader("file.log");

Reader reader = new BufferedReader(new FileReader("file.log"));

看了下面的类图,其实两种reader本质就是一个东西,所以可以直接且方便的扩充功能:

image.png

看到这里,是否发现跟之前说过的适配器模式十分相像,其实他们有一个统一的名称:包装模式。他们都是在包装一个类来实现更多的功能,但区别在于:

  • 适配器模式的意义是要将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的。
  • 装饰器模式不是要改变被装饰对象的接口,而是恰恰要保持原有的接口,但是增强原有对象的功能,或者改变原有对象的处理方式而提升性能

装饰器无论怎么装饰,它和被装饰的类都具备一致的行为,只不过功能更多。