注解与装饰器
对于很多 Java 开发人员来说,注解(Annotation)已经是一个十分熟悉的概念。而在 JavaScript 中(目前仍然是 Stage 2 的 ES Proposal),引入了一个类似的语法——装饰器(Decorator)。
甚至有很多人在生活中不加区分两个的概念,把装饰器也叫做注解。那么,装饰器和注解到底有什么联系与区别呢?
概念
注解(Annotation):仅提供附加元数据支持,并不能实现任何操作。需要另外的 Scanner 根据元数据执行相应操作。
装饰器(Decorator):仅提供定义劫持,能够对类及其方法的定义并没有提供任何附加元数据的功能。
虽然语法上很相似,但在不同的语言中可能使用的是不同的概念:
使用注解(Annotation)的语言:AtScript、Java、C#(叫 Attribute)。
使用装饰器(Decorator)的语言:Python、JavaScript/ECMAScript。
从概念上来说,我们可以很清晰的看出,注解和装饰器在语义上没有任何共性!
注解是给别人看的,影响别人的行为,而该行为并不仅仅由注解决定;装饰器直接拦截,装饰器就是行为改变的全部,装饰器直接改变被装饰对象的行为!
注解正如好人牌子一样,影响别人对你看法;当你吃饭时,装饰器就是那个帮你饭前收拾桌子,饭后擦桌子的人!
Java 中有装饰器模式,但是这个是高度耦合的,AOP就是要去耦合,肯定不能再用Java的装饰器模式了。 而Python的装饰器模式确是解耦的。
在不用的语言,相同的名词意思相反啊?Java装饰器是为了增强类似功能,Python装饰器是为了分离不同功能?
AOP是一种装饰模式吗?
问问题
投票
24
投票
最喜欢
7
我在接受采访时被问到了这个问题。我清楚地知道装饰器模式是什么以及如何使用它。但我在采访中无法思考这个问题。
这是实际问题。
AOP是装饰模式的变体吗?AOP实施与商标装饰模式有何不同?
设计模式 语言不可知的 aop 装饰
分享改善这个问题
于2011年11月13日14:11编辑
叶海亚
62.3k688120
11年11月13日14:09 问
Vinoth Kumar CM
45432371116
添加评论
4答案
活跃的 最老 票
投票
20
投票
接受
我会说AOP(面向方面编程)本身不是一个模式(因此不是我的POV中的一种装饰模式)......它的实现可以通过一个或多个模式完成(包括使用装饰模式)。 .. AOP是一种编程范例恕我直言 - 其他范例是例如OOP,函数式编程或程序式编程......
分享改善这个答案
于11年11月13日14:16 回答
叶海亚
62.3k688120
五
AOP实现主要使用Proxy和Decorator的混合。 - BalusC 11年11月13日15:30
@BalusC:或代码编织。 - 史蒂文 2013年3月30日20:33
AOP的语义在语言层面运行:添加关键字,改变控制流等; 而Decorator完全在OOP的语义中运行(只是覆盖虚拟方法)。这使得Decorator成为一种模式,而AOP则被认定为“语言扩展”。 - rwong 2014年 8月25日23:47
@rwong这取决于它实现的语言,例如,对于AspectJ,是的。对于更动态的语言,它可以只是一个库。 - 戴夫牛顿 2015年5月19日17:59
添加评论
投票
10
投票
我同意Yahia的意见。请注意,虽然方面添加并可能修改现有功能,但它们通常应用于整个方法或类,而不是单个实例。
分享改善这个答案
于11年11月13日14:25 回答
卢塞罗
51.4k491142
1
+1用于突出显示“整个方法/类与单个实例”点:-) - Yahia 11年11月13日在14:29
添加评论
投票
5
投票
我想在某种程度上说,是的,AOP是装饰器模式的一个实现。
对我来说,最大的区别在于它的实施方式以及如何应用。
传统装饰器通常是对象,它们要么显式地组合要装饰的对象,要么由底层对象的扩展点启用。
AOP通常以更“声明”的方式指定 - 传统的装饰器是主线代码的一般部分。
传统装饰器通常仅适用于特定类或接口,并且通常在实例级别应用。AOP(通常)可以在“基础级别”围绕基本上任意的代码包装功能 - 行为将扩展到应用方面的所有实例。这使它能够满足其“交叉功能”的要求:它不一定限于与装饰者一样狭窄的范围。
这取决于基础语言,但有些语言比其他语言更灵活。以上内容更多地适用于“静态”语言(例如Java),而不是像Ruby这样的语言,其中看起来像传统装饰器的东西可以应用于单个实例,或者成为类定义的一部分。
分享改善这个答案
于2011年11月13日14:35编辑
于11年11月13日14:29 回答
戴夫牛顿
138K18208253
添加评论
投票
1
投票
此外,支持跨部门关注拦截的依赖注入框架基本上应用了引擎盖下的装饰模式。将构造方法编织到中间语言中的框架(如在.Net MSIL中)不依赖于接口或继承,这与装饰器模式不同。