常用设计模式之装饰模式

类图

装饰(包装)模式是一种对象功能增强模式。类图如下
完整类图
该类图的是把装饰对象也抽取出一个独立接口。变体是使用DecoratorA,DecoratorB实现Component的方式,不用另外抽取出Decorator接口。

增强对象的方法

功能增强技术有三种,1)继承 2)装饰 3)代理
比较容易跟装饰模式混淆的是继承,代理是另一种模式,在这里就不说了。
比较继承和装饰来说,装饰是比较灵活和方便的,至于为什么这么说,等一下会说清楚。
总的来说,装饰是为了给对象添加一些其他的职责,以完成一些更复杂的功能。

场景

设想一种场景,你做了一个日志接口。其中实现了 记录到控制台,记录到文件等日志子类。
那么现在,你有一种需求,要把其中的 记录到控制台ConsoleLogger的 接口 增加一种能够在配置文件进行控制的方式。这样子,当你在调试状态的时候可以设置为输出,正常运作的时候则可以设置为不输出。
这时候有两种选择,一种是,继承方式, 新建一个类实现ConsuleLogger,在用父类的方法的时候做一个判断。这样可以完成。那么也不需要修改很多地方,只要在创建Log对象的时候实例化为该类即可。当然,如果程序是用了创建型模式来创建的话修改的范围更小。
另一种方式是,新建一个类,以ConsoleLogger作为构造参数(便于理解先用该具体类作为参数)传递给该类。实际该类的方法在实际记录日志的时候调用的时候是调用ConsuleLogger传递进来的参数。

比较

既然两种方式都可以,那么我们就有必要比较一下两种方式了。

  • 首先,装饰模式更为清晰,在继承结构上
  • 其次,更为灵活,假设,如果后面想让其他的日志子类也同样有这种功能,其实在原来的构造参数设置上,我们使用Log接口即可,这也符合面向接口编程原则。把构造参数改成接口之后,那么装饰模式就不用考虑用户想在日志位置实现这种控制了,只需要在运行时传递具体的Log子类对象即可
不适用

当然,该模式也有不适用的地方,即,在这种情况下,某个接口有很多的抽象方法。你只想对该接口子类对象的其中一个方法进行控制。那么在这种情况下如果还用装饰就不太合适。因为你要全部实现这些方法。这种情况下,在java 中的话可以使用动态代理技术。这是另一个方面了。
ps. 在java的io流家族大量使用装饰模式,理解该模式对io流会更容易理解一点。

更多说明

模式是一种指导方针,具体在用是怎么方便怎么来。**理解了那些设计原则就会更明白一些模式的目的了。**例如,本例来说,较为明显的原则,多用组合少用继承原则,比较灵活,这是为什么不推荐继承方式来增强对象的原因;面向接口或者抽象设计,因此装饰者用构造参数用接口方式传递,另一点是为什么要让装饰者实现Component接口,这是为了让外部能够像调用Component子类对象调用装饰对象,对外统一,即能够用Component的地方就一样也可以用Decorator;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值