Proxy模式与Decorator模式的区别

看了一篇文章(http://www.javaworld.com/javaworld/jw-02-2002/jw-0222-designpatterns.html)说到:

两个模式比较相似,因为Both patterns use a proxy that forwards method calls to another object, known as the real subject.

两模式的不同之处在于:with the Proxy pattern, the relationship between a proxy and the real subject is typically set at compile time, whereas decorators can be recursively constructed at runtime。

不是很能理解上面所说的不同之处,请各位指教(最好可以举例说明)。谢谢。

proxy模式和decorator模式都是处理两个类的关系,所不同的是两者关系在何时被建立,英文意思说:proxy模式是在编译时建立关系;而decorator模式则可以在运行时构建。

如果我没有理解错的话:老外视图从编译或运行两者语言状态来描述两者区别,我不敢苟同。

我个人认为:应该从业务应用场景来看待两者区别,而不是拘泥于类关系的如何实现上,不同模式区别都是因为关注点不同,Proxy模式关注的代理两个字,是类的代理,也就是一个类的整体代理,一个原始类可能有多个方法,使用代理类,就要尽量对原始类大部分方法从同一个功能触发进行代理,比如权限代理,进而可以发展到动态代理以及AOP。

而Decorator则侧重于增加职责,至于为一个类多个方法增加的职责是否统一不是其关心的,可能不同方法不同职责。

嗯, 我同意banq 的观点, proxy 是对类的代理,的确强调的是对已有功能的代理, 而 decorator 我也认为更多的是用于增加装饰,来丰富类的内涵

用那种环境去讲解设计模式无关紧要,但一定要通俗、易解

听了BANQ的讲解,体会又深一层,感谢!

实际上他们都是包装了一个类,只不过 Decorator模式 的包装,对于客户段来说是透明的,还可以从业务逻辑方面分析他们的不同.我的一点儿理解,正在研究设计模式,研究中 ----

banq 说的很有道理啊。但是动态与否确实是区分这两个模式的一个方面阿。

proxy模式:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用,相当于你访问代理对象,由代理对象去访问目标对象,这和你直接访问目标对象是一样的
Decorator:实质就是给一个对象动态添加功能,JAVA的IO类就是使用了些模式,一个对象经过包装后,这个对象不但有原来的功能,还有新添加的功能,这些新功能就是定义在Decorator类中的

所以说proxy只是对现在功能作了代理,而decorator不是对现在功能代理,是添加新的功能

>>proxy模式:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用,相当于你访问代理对象,由代理对象去访问目标对象,这和你直接访问目标对象是一样的
Decorator:实质就是给一个对象动态添加功能,JAVA的IO类就是使用了些模式,一个对象经过包装后,这个对象不但有原来的功能,还有新添加的功能,这些新功能就是定义在Decorator类中的

--说到这,我能不能这样理解:
代理对象并不是我们直接要访问的源对象,但用了代理我们通过代理对象访问源对象,那么这个代理对象里有更多的功能,而用Decorator,是变成了一个新的对象,这个对象直接成我们要访问的源对象--其也是包含比我们原对象还多功能的对象。

可以这么理解,代理和装饰器表面上相似,其实内在原因不一样,。

同意banq老师的说法,设计模式不能从具体的类图关系来理解。很多模式不就是用了组合方式来实现的吗?
所以还是要从具体的应用场合来入手,从模式的用意来入手,proxy模式的重点在于代理,也可以说是中介。而decorator模式的用意在于动态的添加新的功能,被装饰的对象不一定是一个功能丰富的对象,但是通过一步一步的装饰,那个被装饰对象的功能就丰富起来了。所以decerator模式也提供给我一种如何把一个简单对象的功能进行进一步的丰富,并且这种丰富建立在没有改变原来对象接口和功能的前提下。

我是这么理解的:
proxy模式: 他的功能是起代理作用,是一种结构性的装饰,属于结构模式,具有静态性,所以英文解释里用了“at compile time”,说明这个不是在运行过程中可以动态改变的;在代理过程中可以添加其它功能,但这些功能不是对源对象本身功能的增强,而是出于系统设计的一种考虑,如:增加访问权限,或者增加日志等等,这些附加功能一般都是通用功能,跟源对象没有什么特定联系。
decorator模式:起装饰作用,是一种对源对象功能本身进行加强和修饰性的行为,属于行为模式。他增加的功能跟源对象功能本身是有特定联系的,这些附加功能一般不是通用功能。英文中的“at runtime”可能是指,在运行时可以有实现同一接口的不同实现类来装饰一个源对象,产生不同的附加功能,是动态生成的,而proxy对象只有一个,可以用单例对象实现。
不知道我的理解对不对?请banq老师指点一下。

2006年05月13日 17:57 "banq"的内容
我个人认为:应该从业务应用场景来看待两者区别,而不是拘泥于类关系的如何实现上,不同模式区别都是因为关注点不同,Proxy模式关注的代理两个字,是类的代理,也就是一个类的整体代理,一个原始类可能有多个方法,使用代理类,就要尽量对原始类大部分方 ...

不错,学习了