设计模式随笔-也说说“从Adapter模式到Decorator模式”

吕震宇

终于有时间写点什么了,可以前酝酿好的东西似乎一下子都忘记了。这几天看了wayfarer的《《让僵冷的翅膀飞起来》系列之三——从Adapter模式到Decorator模式》后,感觉这样的文章真应当多发一些,激发思路。只是本来想用高级评论,却发现默认高级评论使用的是CuteEditor,在我的机器上根本无法使用,鼠标始终是沙漏(不知道是不是跟防火墙有关),而自己又无法选择使用什么编辑器编辑高级评论,所以才不得不写篇文章说说我的想法,看来又要有劳dudu了。

当初提出使用Decorator模式的是我,可现在提出异议的又是我,不要说我胡搅蛮缠,讨论中才能增长经验呀。wayfarer与idior的评论对我有很大启发,但我发现现在似乎有些问题没有定义清楚,导致在探讨解决办法时模棱两可。第一,原有设计是否不允许有任何变动。wayfarer的文章中,似乎默认是不允许对原有系统进行任何修改,而是通过增加新代码的方式提供新功能。否则以下的设计就应当能够解决问题了:

设计模式随笔-也说说“从Adapter模式到Decorator模式” _第1张图片

第二,新增加的Resize方法是否与RM或MPEG的具体实现纠缠不清。如果Resize的实现相对独立,只要针对抽象VideoMedia中的方法和属性就可以完成所有功能,那么使用Decorator模式无疑是个不错的选择,丑陋的"if (!(vedio is RM))"也可以不用出现在代码当中(具体可以参考wayfarer的原文)。设计如下:

设计模式随笔-也说说“从Adapter模式到Decorator模式” _第2张图片

因为SizeDecorator中的Resize方法只针对VideoMedia中的抽象方法执行操作,所以系统也就没有必要判断VideoMedia具体是RM还是MPEG,多态性自动替我们解决了这个问题。

但是,正如wayfarer和idior所说的,Decorator并不适合为一个对象添加新功能。否则当对一个VideoMedia应用多个Decorator时,从类型上讲用户只能看到最后一次Decorate时加入的新功能,以前的Decorator所起的作用被"屏蔽"了。

除此之外,如果Resize方法依赖于具体的VideoMedia类型,那恐怕带来的就是灾难了。因为在编写Resize方法时,必须清楚的知道你是对RM操作还是对MPEG操作,VideoMedia类型的_video也就形同虚设,丑陋的"if (!(vedio is RM))"也必不可免了。在这种情况下,还不如使用"类适配器模式"好(可以参考《《《让僵冷的翅膀飞起来》系列之二——从实例谈Adapter模式)。

第三,Visitor模式是否可行?其实,如果将条件限定为不允许改变任何原有代码的化,Visitor模式根本没有用武之地。因为Visitor模式象踢皮球一样需要一个"回传"功能,才能针对具体类型具体操作。可添加"回传(允许被Visit)"功能必须修改VideoMedia、RM与MPEG,这样就违反了规则。

所以,我们应将尽量"针对抽象编程"。这样可以防止Resize方法过分依赖于具体。否则,不管使用哪种模式,都会"牺牲"大量的代码。除此之外,当我们必须了解类型信息时,同时又要保证类型匹配(RMDecorator只能装饰RM)时,可以考虑使用抽象工厂(取其意),将RMDecorator、与RM认为是一个产品族。

另外,如果需要动态为现有对象添加多个方法时,是否可以考虑使用DynamicProxy,借助Mixin机制为一个类动态添加行为。但是我刚刚开始学习DynamicProxy、AOP和Mixin,感觉在需要我们了解具体类型后再进行操作的场合下,这些机制似乎帮不了什么太大的忙。如果有这方面的高手,还望指点一二。

你可能感兴趣的:(设计模式随笔-也说说“从Adapter模式到Decorator模式” )