再议:装饰器模式和代理模式的区别

在典型的例子上,两者是非常好区分的。如spring的AOP、远程代理类、JDK的proxy,都是代理模式。JDK里的输入/输出器是很典型的装饰器模式! 
但在有些场景上,对设计模式入门的新手,还是有点难区分,我曾经也一度为此困惑。 
两个模式的UML类图基本没区别,都是实现同一个接口,一个类包装另一个类。 

两者的定义 
装饰器模式:能动态的新增或组合对象的行为。 
代理模式:为其他对象提供一种代理以控制对这个对象的访问. 
装饰模式是“新增行为”,而代理模式是“控制访问”。关键就是我们如何判断是“新增行为”还是“控制访问”。 

来看一个例子 
之前设计的搜索引擎检索模块: 

 

Searcher:检索类接口 
IllegalKeywordFilterSearcher:非法关键词过滤检索类,即如果搜索关键词里包含非法关键词,直接返回空结果集。 
CachedSearcher:缓存检索类,相同检索条件缓存已经有数据,返回缓存里的结果集。 
DistributedSearcher:分布式检索类,调用多台服务器的检索服务,然后合并最终的结果集。 
LocalSearcher:本地检索类,只能从当台服务器上检索结果 
HightLightSearcher:高亮检索类,操作结果集,找到跟搜索条件最相关的片段,并且关键词上高亮。 

其中HightLightSearcher很明显是装饰类,新增了高亮的行为。 
CachedSearcher是代理类,可能也没疑义,因为可能听说过“缓存代理”的说法。 

IllegalKeywordFilterSearcher就不好确定是代理类还是装饰类,可以理解是控制访问,也可以理解成是新增行为,毕竟它是业务需求,总觉得业务需求应该属于行为。 

看了这篇文章之后 difference-between-decorator-and-proxy-patterns 就非常明确了。 

原句:I think we’re all aware that the decorator pattern is used to add behavior to existing code. This does not stop at one kind of behavior but any number of different things that we want to do. 
意译:装饰类只能新增行为,不能跳过其他的任何一个行为。 

IllegalKeywordFilterSearcher如果检测到有敏感关键词,就直接返回空结果了,不会再调用其他检索类了,所以不是 
装饰类,而是代理类。 

当然,有些类可能既有控制访问的逻辑,也有新增行为逻辑。比如高亮和缓存整合在一个类里,但是违反了单一职责原则,觉得也没讨论的必要。 

网上已经有很多关于两者区别的文章,但是评判的标准的都不是非常明确,我不知道大家有没有类似的困惑。 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值