Java中“装饰模式”和“代理模式”有啥区别( 三 )


These differences are significant because they capture solutions to specific recurring problems in object-oriented design. But that doesn\u0026#39;t mean these patterns can\u0026#39;t be com- bined. You might envision a proxy-decorator that adds functionality to a proxy, or a decorator-proxy that embellishes a remote object. Although such hybrids might be useful (we don\u0026#39;t have real examples handy), they are divisible into patterns that are useful. 第一段说的是代理模式,侧重于不能直接访问一个对象,只能通过代理来间接访问,比如对象在另外一台机器上,或者对象被持久化了,对象是受保护的。对象在另外一台机器上,其实就是rpc,感兴趣的可以看看dubbo的源码本地反问的其实就是远程对象的代理,只不过代理帮你做了访问这个对象之前和之后的很多事情,但是对使用者是透明的了。对象被持久化了,比如mybatis的mapperProxy。通过mapper文件自动生成代理类。第三种,对内核对象的访问。
第二段说的是装饰器模式是因为没法在编译器就确定一个对象的功能,需要运行时动态的给对象添加职责,所以只能把对象的功能拆成一一个个的小部分,动态组装,感兴趣的可以看看dubbo的源码,里面的mock,cluster,failover都是通过装饰器来实现的。因为这些功能是由使用者动态配置的。但是代理模式在编译器其实就已经确定了和代理对象的关系。
第三段说的是,这个两个设计模式是为了解决不同的问题而抽象总结出来的。是可以混用的。可以在代理的基础上在加一个装饰,也可以在装饰器的基础上在加一个代理。感兴趣的去看看dubbo源码,里面就是这么实现的。

■网友
装饰器模式应当为所装饰的对象提供增强功能,而代理模式对所代理对象的使用施加控制,并不提供对象本身的增强功能。
From:《java与模式》阎宏编著

■网友
两者都是加东西但是装饰模式加的是类似的职能,比如拓展一个算法类,比如给文本框加滚动条而代理模式加的是全新的东西,职能不在同一个方面,比如写日志,计数器,权限控制刚学设计模式,不知道说得对不对
■网友
这么久问题了,从一个新的角度回答一下。
相同:都是增强被代理对象的功能。
【Java中“装饰模式”和“代理模式”有啥区别】 区别:是否进行功能增强、何时进行功能增强,这个决策权交给谁是不同的。
例如一个对象proxied的方法m的调用需要鉴定被调用这的权限,鉴权这个动作是m的功能之外的补充,现在可以写一个Proxy类,在调用proxied.m之前的逻辑里实现鉴权。
或者写一个Decorator类,接收一个Target对象作为被装饰者,调用target.m之前的逻辑里实现鉴权。
都是要写实现新的功能逻辑,之后委托老的对象执行老的功能。

重点在于构造Decorator的时候需要原obj参与,而构造Proxy的时候不可以也不需要拿到原obj,那么第三方程序员已经拿到obj的情况下,可以决定是什么情况下对这个obj进行增强,而代理就不行了,第三方程序员拿到的是已经被代理好的,功能已经增强。

所以考虑这两种设计模式的时候,要分清楚你自己的开发者角色
如果是别人A已经给你一个类,你需要做好增强给第三方C使用增强的类,且C不可以直接使用未增强的类对象,那么你这个开发者应该使用代理模式,把你可以获得的类对象封装到自己的代理类;
如果你希望把何时增强功能的这个决策权交给C,即C既可以使用增强的类对象,也可以使用不增强的对象,决定权在于C,那么这个时候你应该使用装饰器模式。

■网友
Decorator Pattern focuses on dynamically adding functions to an object, while Proxy Pattern focuses on controlling access to an object.


推荐阅读