本页使用了标题或全文手工转换

面向切面的程序设计

维基百科,自由的百科全书
(重定向自面向侧面的程序设计
跳到导航 跳到搜索

面向切面的程序设计(Aspect-oriented programming,AOP,又译作面向方面的程序设计剖面导向程序设计),是计算机科学中的一种程序设计思想,旨在将横切关注点与业务主体进行进一步分离,以提高程序代码的模块化程度。通过在现有代码基础上增加额外的通知(Advice)机制,能够对被声明为“切点(Pointcut)”的代码块进行统一管理与装饰,比如说:“对所有方法名以set*开头的方法添加后台日志”。该思想使得开发人员能够将与代码核心业务逻辑关系不那么密切的功能(如日志功能)添加至程序中,同时又不降低业务代码的可读性。面向切面的程序设计思想也是面向切面软件开发的基础。

简介[编辑]

面向切面的程序设计将代码逻辑切分为不同的模块(即关注点英语Concern (computer science),一段特定的逻辑功能)。几乎所有的编程思想都涉及代码功能的分类,将各个关注点(Concern)封装成独立的抽象模块(如函数、过程、模块、类以及方法等),后者又可供进一步实现、封装和重写。部分关注点“横切”程序代码中的数个模块,即在多个模块中都有出现,它们即被称作横切关注点(Cross-cutting concerns, Horizontal concerns)。

日志功能即是横切关注点的一个典型案例,因为日志功能往往横跨系统中的每个业务模块,即“横切”所有有日志需求的类及方法体。而对于一个信用卡应用程序来说,存款、取款、帐单管理是它的核心关注点,日志和持久化将成为横切整个对象结构的横切关注点。

切面的概念源于对面向对象的程序设计计算反射的融合。面向切面编程语言拥有很多类似于元对象协议的功能,但有更多的限制。切面相关的编程概念包括主题英语Subject-oriented programming混入委托英语Delegation (computing)。使用面向切面思想的其他方式有复合过滤器英语Composition Filters和Hyper/J的hyperslices方式。

历史[编辑]

“面向切面的程序设计”这一术语出现的具体时间已经不可考证了,但该词是由施乐帕洛阿尔托研究中心的Chris Maeda首先提出的。术语“横切”是由Gregor Kiczales英语Gregor Kiczales提出的。同许多重大的技术创新一样,面向切面的程序设计,也是在不同的地方被独立发展出来。面向切面编程的早期工作,主要是由下面几个机构和人员作出的:

  • 施乐帕洛阿尔托研究中心:Gregor Kiczales、John Lamping、Cristina Videira Lopes等人,进行的早期工作,有关于反射机制和元对象协议;1997年Gregor Kiczales发表了论文《面向切面的程序设计》;代表系统是基于元对象协议的面向切面程序设计系统和AspectJ英语AspectJ
  • 国际商用机器公司托马斯·J·沃森研究中心:William Harrison、Harold Ossher、Peri Tarr等人,在1980年代末进行的早期工作,有关于软件开发环境与工具集成;后来提出多维关注点分离(MDSOC);代表系统是Hyper/J。
  • 美国东北大学:Karl Lieberherr等人,进行的早期工作是研究软件演化,提出了得墨忒耳定律、传播模式、适应性程序设计;代表系统是Demeter/C++和Demeter/Java。
  • 荷兰特温特大学:Mehmet Aksit等人的代表系统是复合过滤器。

基本概念[编辑]

关注点英语Concern (computer science)是对软件工程有意义的小的、可管理的、可描述的软件组成部分,一个关注点通常只同一个特定概念或目标相关联。传统的程序设计语言,以一种线性的文本来描述软件,只采用一种方式比如类,将软件分解成模块;这导致某些关注点比较好的被捕捉,容易进一步组合、扩展;但还有一些关注点没有被捕捉,弥散在整个软件内部。

关注点分离(SOC)是标识、封装和操纵只与特定概念、目标相关联的软件组成部分的能力,即标识、封装和操纵关注点的能力。分离关注点使得解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中不再含有针对特定领域问题代码的调用,业务逻辑同特定领域问题的关系通切面来封装、维护,这样原本分散在在整个应用程序中的变动就可以很好的管理起来。

核心关注点是一个软件最主要的关注点。在传统的程序设计语言中,将软件分解成模块的主要方式,是支配性分解,即按主关注点进行模块分解。用来描述、设计、实现一个给定关注点的软件构造单位是方法。如果两个关注点的实现的方法存在交集,则称谓这两个关注点相互横切(Crosscut)。

面向切面的程序设计的核心概念,是从核心关注点中分离出横切关注点。面向切面编程,在支配性分解的基础上,提供叫做切面英语Aspect (computer programming)(Aspect)的一种辅助的模块化机制,这种新的模块化机制可以捕捉横切关注点。

连接点模型[编辑]

面向切面语言的通知相关构件,定义了一个连接点模型(JPM)。一个JPM定义了三种东西:

  1. 何时通知可以运行。这些叫做连接点英语join point,因为在一个运行的程序中,它们是可以有用的连接上额外行为的点。一个连接点要有用,它必需是可寻址的,并且对普通程序员是可理解的。它还应该经历无关紧要的程序变更而保持稳定,使得一个切面经历这种变更而保持稳定。很多AOP实现支持方法执行和字段引用作为连接点。
  2. 规定(或量化)连接点的方式,这叫做切点英语pointcut。切点确定是否匹配一个给定连接点。最有用的切点语言使用像基础语言的语法(例如AspectJ英语AspectJ使用Java签名),并允许通过命名和组合来重新使用。
  3. 指定在连接点要运行的代码的手段。AspectJ英语AspectJ称之为通知英语Advice (programming),并且可以在连接点之前、之后和周围运行。一些实现还支持在一个切面中定义另一个类上的一个方法。

连接点模型可以基于暴露的连接点、如何规定连接点、在连接点上允许的操作,和可以表达的结构性增强来进行比较。

AspectJ的连接点模型[编辑]

所有有效的Java程序也是有效的AspectJ程序,但是AspectJ容许编程者定义叫切面英语Aspect (computer programming)的特殊构造。切面包含一些对于标准类不能获得到的实体。它们是扩展方法、切点和通知。

扩展方法英语Extension method允许编程者从这个切面内向现存的增加方法、字段或接口。下面例子向类Point增加一个acceptVisitor方法(参见访问者模式):

aspect VisitAspect {
  void Point.acceptVisitor(Visitor v) {
    v.visit(this);
  }
}

在AspectJ中连接点包括:方法或构造子调用或执行,一个类或对象的初始化,字段读或写访问,异常处理等。它们不包括:循环、super调用,throw子句,多个语句等。 切点是通过组合“原始切点指示符”(PCD)来规定的。

“种类”PCD匹配特定种类的连接点(比如方法执行),并且倾向于接受类似Java签名作为输入。一个这种切点如下所示:

execution(* set*(*))

这个切点匹配一个方法执行连接点,如果这个方法名字开始于set,并且精确的只有一个任何类型的实际参数。

“动态”PCD检查运行时间类型和绑定变量。例如:

this(Point)

这个切点在当前执行对象是类Point的实例之时匹配。注意一个类的未限定名字可以通过Java的正常类型查找来使用。

“范围”PCD限制连接点的词法作用域。例如:

within(com.company.*)

这个切点匹配在com.company包中任何类型的任何连接点。*是一种形式的通配符,它用来匹配具有一个签名的任何东西。

切点可以复合和命名来重新使用。例如:

pointcut set() : execution(* set*(*) ) && this(Point) && within(com.company.*);

这个切点匹配一个方法执行连接点,如果这个方法名字开始于set,并且this是在com.company包中类型Point的实例。它可以使用名字set()来提及。

通知规定在(通过切点指定的)一个连接点(之前、之后或周围)运行特定代码(指定如若一个方法中的代码)。AOP运行时间系统,在这个切点匹配一个连接点的时候,自动调用通知。例如:

after() : set() {
  Display.update();
}

这在效果上指定了:“如果set()切点匹配这个连接点,在连接点完成之后,运行代码Display.update()。”

实现[编辑]

下列编程语言已经实现了AOP,于语言之内或外部库:

参考文献[编辑]

  1. ^ Numerous: Afterthought 互联网档案馆存档,存档日期2016-03-15., LOOM.NET 互联网档案馆存档,存档日期2008-08-27., Enterprise Library 3.0 Policy Injection Application Block 互联网档案馆存档,存档日期2007-01-19., AspectDNG 互联网档案馆存档,存档日期2004-09-29., DynamicProxy 互联网档案馆存档,存档日期2015-12-05., Compose* Wikiwix的存档,存档日期2005-08-21, PostSharp 互联网档案馆存档,存档日期2016-05-03., Seasar.NET 互联网档案馆存档,存档日期2006-07-25., DotSpect (.SPECT) 互联网档案馆存档,存档日期2006-03-31., Spring.NET 互联网档案馆存档,存档日期2006-04-02. (as part of its functionality), Wicca and Phx.Morph 互联网档案馆存档,存档日期2006-12-07., SetPoint 互联网档案馆存档,存档日期2008-10-07.
  2. ^ PostSharp. [2022-02-13]. (原始内容存档于2022-07-05). 
  3. ^ Welcome to as3-commons-bytecode. as3commons.org. [5 May 2018]. (原始内容存档于3 October 2014). 
  4. ^ Ada2012 Rationale (PDF). adacore.com. [5 May 2018]. (原始内容存档 (PDF)于18 April 2016). 
  5. ^ Function Hooks. autohotkey.com. [5 May 2018]. (原始内容存档于17 January 2013). 
  6. ^ Several: AspectC++, FeatureC++页面存档备份,存于互联网档案馆), AspectC 互联网档案馆存档,存档日期2006-08-21., AspeCt-oriented C 互联网档案馆存档,存档日期2008-11-20., Aspicere
  7. ^ Cobble. vub.ac.be. [5 May 2018]. [永久失效链接]
  8. ^ AspectCocoa. neu.edu. [5 May 2018]. (原始内容存档于26 October 2007). 
  9. ^ ColdSpring Framework: Welcome. 5 November 2005 [5 May 2018]. (原始内容存档于5 November 2005). 
  10. ^ Closer Project: AspectL.. [11 August 2015]. (原始内容存档于23 February 2011). 
  11. ^ infra - Frameworks Integrados para Delphi - Google Project Hosting. [11 August 2015]. (原始内容存档于9 September 2015). 
  12. ^ meaop - MeSDK: MeObjects, MeRTTI, MeAOP - Delphi AOP(Aspect Oriented Programming), MeRemote, MeService... - Google Project Hosting. [11 August 2015]. (原始内容存档于10 September 2015). 
  13. ^ Google Project Hosting. [11 August 2015]. (原始内容存档于25 December 2014). 
  14. ^ RemObjects Cirrus. codegear.com. [5 May 2018]. (原始内容存档于23 January 2012). 
  15. ^ Emacs Advice Functions. gnu.org. [5 May 2018]. (原始内容存档于24 October 2011). 
  16. ^ Monads allow program semantics to be altered by changing the type of the program without altering its code: De Meuter, Wolfgang. Monads As a theoretical basis for AOP. International Workshop on Aspect-Oriented Programming at ECOOP. 1997: 25. CiteSeerX 10.1.1.25.8262可免费查阅.  Tabareau, Nicolas; Figueroa, Ismael; Tanter, Éric. A Typed Monadic Embedding of Aspects. Proceedings of the 12th Annual International Conference on Aspect-oriented Software Development. Aosd '13. March 2013: 171–184 [2022-03-02]. ISBN 9781450317665. S2CID 27256161. doi:10.1145/2451436.2451457. (原始内容存档于2018-11-06).  Type classes allow additional capabilities to be added to a type: Sulzmann, Martin; Wang, Meng. Aspect-oriented programming with type classes. Proceedings of the 6th Workshop on Foundations of Aspect-oriented Languages. March 2007: 65–74. ISBN 978-1595936615. S2CID 3253858. doi:10.1145/1233833.1233842. .
  17. ^ Numerous others: CaesarJ 互联网档案馆存档,存档日期2008-12-19., Compose* Wikiwix的存档,存档日期2005-08-21, Dynaop 互联网档案馆存档,存档日期2007-07-24., JAC 互联网档案馆存档,存档日期2004-06-19., Google Guice (as part of its functionality), Javassist 互联网档案馆存档,存档日期2004-09-01., JAsCo (and AWED) 互联网档案馆存档,存档日期2005-04-11., JAML 互联网档案馆存档,存档日期2005-04-15., JBoss AOP 互联网档案馆存档,存档日期2006-10-17., LogicAJ 互联网档案馆存档,存档日期2006-05-04., Object Teams 互联网档案馆存档,存档日期2005-08-31., PROSE 互联网档案馆存档,存档日期2007-01-24., The AspectBench Compiler for AspectJ (abc) 互联网档案馆存档,存档日期2014-12-16., Spring framework (as part of its functionality), Seasar, The JMangler Project 互联网档案馆存档,存档日期2005-10-28., InjectJ 互联网档案馆存档,存档日期2005-04-05., GluonJ 互联网档案馆存档,存档日期2007-02-06., Steamloom 互联网档案馆存档,存档日期2007-08-18.
  18. ^ Many: Advisable 互联网档案馆存档,存档日期2008-07-04., Ajaxpect 互联网档案馆存档,存档日期2016-07-09., jQuery AOP Plugin 互联网档案馆存档,存档日期2008-01-13., Aspectes Wikiwix的存档,存档日期2006-05-08, AspectJS 互联网档案馆存档,存档日期2008-12-16., Cerny.js 互联网档案馆存档,存档日期2007-06-27., Dojo Toolkit 互联网档案馆存档,存档日期2006-02-21., Humax Web Framework 互联网档案馆存档,存档日期2008-12-09., Joose 互联网档案馆存档,存档日期2015-03-18., Prototype - Prototype Function#wrap 互联网档案馆存档,存档日期2009-05-05., YUI 3 (Y.Do) 互联网档案馆存档,存档日期2011-01-25.
  19. ^ Using built-in support for categories (which allows the encapsulation of aspect code) and event-driven programming (which allows the definition of before and after event handlers).
  20. ^ AspectLua. [11 August 2015]. (原始内容存档于17 July 2015). 
  21. ^ MAKAO, re(verse)-engineering build systems. [11 August 2015]. (原始内容存档于24 July 2012). 
  22. ^ McLab. [11 August 2015]. (原始内容存档于24 September 2015). 
  23. ^ AspectML - Aspect-oriented Functional Programming Language Research. [11 August 2015]. (原始内容存档于5 December 2010). 
  24. ^ Adam Kennedy. Aspect - Aspect-Oriented Programming (AOP) for Perl - metacpan.org. [11 August 2015]. (原始内容存档于31 August 2013). 
  25. ^ Several: PHP-AOP (AOP.io) Wikiwix的存档,存档日期2014-08-18, Go! AOP framework 互联网档案馆存档,存档日期2013-03-01., PHPaspect 互联网档案馆存档,存档日期2016-08-22., Seasar.PHP 互联网档案馆存档,存档日期2005-12-26., PHP-AOP, Flow 互联网档案馆存档,存档日期2018-01-04., AOP PECL Extension 互联网档案馆存档,存档日期2017-04-11.
  26. ^ bigzaphod.org is coming soon. www.bigzaphod.org. [5 May 2018]. (原始内容存档于20 April 2016). 
  27. ^ Several: PEAK 互联网档案馆存档,存档日期2005-04-09., Aspyct AOP, Lightweight Python AOP 互联网档案馆存档,存档日期2004-10-09., Logilab's aspect module 互联网档案馆存档,存档日期2005-03-09., Pythius 互联网档案馆存档,存档日期2005-04-08., Spring Python's AOP module 互联网档案馆存档,存档日期2016-03-04., Pytilities' AOP module 互联网档案馆存档,存档日期2011-08-25., aspectlib 互联网档案馆存档,存档日期2014-11-05.
  28. ^ PLaneT Package Repository : PLaneT > dutchyn > aspectscheme.plt. [11 August 2015]. (原始内容存档于5 September 2015). 
  29. ^ AspectR - Simple aspect-oriented programming in Ruby. [11 August 2015]. (原始内容存档于12 August 2015). 
  30. ^ Dean Wampler. Home. [11 August 2015]. (原始内容存档于26 October 2007). 
  31. ^ gcao/aspector. GitHub. [11 August 2015]. (原始内容存档于4 January 2015). 
  32. ^ AspectS. tu-ilmenau.de. [5 May 2018]. (原始内容存档于6 January 2006). 
  33. ^ MetaclassTalk: Reflection and Meta-Programming in Smalltalk. [11 August 2015]. (原始内容存档于29 July 2015). 
  34. ^ WEAVR. iit.edu. [5 May 2018]. (原始内容存档于12 December 2008). 
  35. ^ aspectxml - An Aspect-Oriented XML Weaving Engine (AXLE) - Google Project Hosting. [11 August 2015]. (原始内容存档于12 September 2015). 

站外链接[编辑]