前言编程
装饰者设计模式原本是很经常使用的模式,经常使用到随处可见,jdk的bio设计都是遵循这个模式的,偶然的机会发现,貌似jdk中bio的装饰者模式和设计模式中的装饰者设计模式却有点本质上的不一样,可是仔细想一想,貌似bio的设计貌似还有点违背设计模式的本意,此文中把装饰者模式说成无用,是由于他定义的这种规范的玩法,你们貌似并不听从,反而更喜欢jdk中的用法。设计模式
类图spa
这个类图你们也并不陌生,具体的被装饰的类和装饰者都是遵循同一个规范,component,此处若是component没有公共的定义方法,那就是妥妥的面向接口编程。看这个用法咱们也能猜到怎么用,先建立被装饰的类,而后用装饰类去修饰被装饰的类,而后把引用给component,调用operation的时候就把装饰的效果显示出来,若是需求变动,那么直接把装饰组合出来的过程改改,其余代码不须要改变。设计
jdk bio的用法代理
做为装饰者模式的典型,他的类图彻底和上面的类图吻合,可是咱们的用法却大大不一样,咱们包装后的IO类,咱们不多直接让接口来做为引用,每个装饰类都带了本身的新特性,API都不同了。咱们想要用包装类的功能就必须使用包装类的引用,不然就切面了,咱们能用到的只有接口的方法。他的侧重是不一样的包装是不一样的功能,相似readline,只有bufferedreader有,咱们想用只能依靠这个包装类,可是类自己也遵循接口,因此也能传递给接口,可是要损失包装的特性。component
两种用法的对比对象
单纯从软件设计讲,jdk io的设计扩展性很差,由于你选择包装,原本就是但愿调用统一的方法,这样对代码的修改最小。但现实是咱们若是不用具体的类没法增长新的功能。也就是说你想体现新的功能的话,后面的代码基本要重写。你们公有的那部分方法压根没有加强到,这样写确定会带来不小的隐患,但很特殊的是,他设计的是IO,通常读取完就over,有传递的可能性,可是用接口传过去后从新包装一下又可使用了,反正是各自包装各自的,公有的方法都不用,这样下来反而也没什么影响。要选择这么使用的话必定得慎重,用很差就带来不少麻烦。
继承
适合场景接口
一看类图,你们基本就能感受这个更像补救型的模式,就是原来的类都实现好了,如今忽然要改需求,给里面的部分类的方法都增长一种或者多种功能,这样装饰者模式就派上用场了,直接在建造对象的地方加一段装饰,固然这个前提都是被装饰的类和装饰的类都是能够估计的,遇到不可估计的状况仍是直接用aop动态代理吧,不要再考虑装饰模式。既然是补救行的,那么也是有必定要求的。
文档
起码最初的类图是这样的,要否则还要添加接口等等(这个确定是不可取的),POJO的话仍是用动态代理的好。
另一种适合状况就是多继承,要对中间继承类须要增长,这种状况用装饰者模式不会影响子类的功能。
和静态代理的区别
其实文中屡次提到代理,其实在功能单一的状况下,代理和装饰均可以,我最后想一想仍是从功能上作点区别,装饰者适合新增的功能能够互相组合的状况,及装饰类和装饰类是能够叠加操做的,而且被装饰的方法仍是较少的,装饰的类的个数也是较少的。静态代理更适合类中方法不少,可是只会代理一层,出现多层代理基本就是不合理的,典型的就是datasource中用本身的connection类代理jdbc中的connection类。
最后说几句
其实用装饰者模式带来种种功能上的好处,可是一旦出现问题,你本身写的代码还好,要是让纯粹不知道的人走断点找问题,那跟断点可就费事了,因此必定留好设计文档和把类的名字起的见字生义。