你们在生产软件中使用AOP(面向切面编程)吗?

38

AOP 是我认为很有趣的编程范式。然而,在 stackoverflow 上还没有关于它的讨论(至少我找不到)。你们对此有什么看法?在项目中是否使用 AOP?或者您认为它是一个小众技术,不会存在很长时间或不会进入主流(像 OOP 一样,在理论上至少 ;))?

如果您确实使用 AOP,请告知您使用的工具。 谢谢!

11个回答

23

Python支持AOP,通过在运行时动态修改其类(在Python中通常称为猴子补丁而不是AOP)。以下是一些使用AOP的用例:

  1. 我有一个网站,其中每个页面都是由一个Python函数生成的。我想将一个类的所有生成的网页设置为需要密码保护。AOP来拯救;在调用每个函数之前,我进行适当的会话检查,并在必要时进行重定向。

  2. 我想在程序的实际使用过程中对一堆函数进行日志记录和性能分析。AOP允许我计算时间并将数据打印到日志文件中,而无需实际修改任何这些函数。

  3. 我有一个模块或类充满了不支持多线程的函数,在某些多线程代码中使用它。一些AOP在这些函数调用周围添加锁定,而无需进入库并更改任何内容。

这种情况并不经常发生,但每当出现时,猴子补丁非常有用。Python还有装饰器,实现装饰者模式(http://en.wikipedia.org/wiki/Decorator_pattern)以实现类似的功能。

请注意,动态修改类还可以让您解决第三方库中的错误或添加功能,而无需实际修改该库。我几乎从不需要这样做,但出现过几次,这非常有用。


15

是的。

针对安全等方面的正交问题,最好采用AOP(面向切面编程)拦截。无论是自动完成(通过依赖注入容器之类的东西)还是手动完成,对于最终目标来说都不重要。

例如,在我管理的开源项目xUnit.net中,“before/after”属性就是一种AOP-style方法拦截的形式。您可以使用这些属性装饰测试方法,在测试方法运行之前和之后调用您的代码。它可用于设置数据库并回滚结果、更改测试运行时的安全上下文等方面。

另一个例子是ASP.NET MVC中的过滤器属性,也像专门的AOP-style方法拦截器。例如,其中一个允许您指定在操作方法中发生未处理错误时应如何处理。

许多依赖注入容器,包括Castle Windsor和Unity,都支持此行为,无论是“内置”还是通过扩展实现。


1
在宣称某个东西是最好的时要小心。许多专家认为能力模型是实现安全的最佳方式,而AOP则是一件可怕的事情。 - L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
@Brad,你说有些事情最好用AOP来完成。你能解释一下用AOP的优势与传统方式相比到底在哪里吗? - Pacerier

9

我不明白如何在不使用AOP的情况下,以干净的方式处理像日志记录、安全性、事务管理、异常处理等交叉关注点。

任何使用Spring框架(可能约占Java企业开发人员的50%)的人都在使用AOP,无论他们是否知道。


2
你介意解释一下 Log([arguments]) 到底有什么不规范的地方吗?它会带来哪些问题? - Pacerier
1
@Pacerier,刚看了一些文档,来晚了 :) .... 有些人认为你不应该写那些句子,因为它们不干净,也就是说,与你打算解决的问题无关。 - davidmpaz

4
TerraCotta,我们广泛地使用AOP和字节码仪器来与第三方软件进行集成和监控。例如,我们的Spring integration很大程度上是通过使用aspectwerkz实现的。简而言之,我们需要在各个关键点拦截对Spring bean和bean工厂的调用,以便将它们聚集起来。
因此,AOP可用于与无法修改的第三方代码进行集成。然而,我们发现存在一个巨大的陷阱-如果可能的话,请仅在连接点中使用第三方公共API,否则您会冒着在下一个小版本发布中由于某个私有方法的更改而破坏您的代码的风险,并且这将成为一场维护噩梦。

4

AOP和事务划分是天作之合。我们使用Spring AOP @Transaction注释,它比我在其他任何地方看到的都更容易和直观地进行事务划分。


3
我们在一个大型项目中使用了AspectJ相当长的时间。该项目由几个Web服务组成,每个服务都有几个函数,是一个复杂的文档处理/查询系统的前端。代码量大约有75k行。我们使用切面来实现两个相对较小的功能。
首先是跟踪应用程序流程。我们创建了一个切面,在每次函数调用之前和之后运行,以打印出“进入'函数'”和“退出'函数'”。通过函数选择器(可能是切入点?我不记得正确的名称),我们能够将其作为调试工具,选择在给定时间内要跟踪的函数。这是我们项目中使用方面的一个非常好的例子。
第二件事是应用程序特定的指标。我们在Web服务方法周围放置了方面,以捕获时间、对象信息等,并将结果转储到数据库中。这很不错,因为我们可以捕获这些信息,但仍然将所有的捕获代码与执行实际工作的“真正”代码分开。
我读过一些关于方面可以带来的好的解决方案的文章,但我仍然不相信它们可以做任何你不能用“正常”的技术做到的事情(也许更好)。例如,我想不出我们的任何项目需要的主要功能或功能,如果没有方面,就不能像没有方面一样容易地完成 - 我发现方面有用的是我提到的那些较小的事情。

对不起,这些是Python项目吗? - Adam Hughes

1

我们在会话门面中使用AOP来为我们的客户提供一个一致的框架来定制我们的应用程序。这样可以使我们暴露一个单一的定制点,而不必为每个方法添加手动挂接支持。

此外,AOP为其他事务设置和拆卸以及通常的日志记录等提供了单一的配置点。总体而言,比手动完成所有这些工作要更易于维护。


1
我所工作的主要应用程序包含一个脚本宿主。面向切面编程允许宿主在决定是否将脚本加载到应用程序域之前检查脚本的属性。由于一些脚本相当繁琐,这使得运行时加载速度更快。
我们还使用和计划使用大量属性来控制编译器、流程控制和IDE调试等事项,这些属性不需要成为最终分发应用程序的一部分。

1

我们使用PostSharp作为我们的AOP解决方案。我们目前使用缓存、错误处理和数据库重试方面,并正在将我们的安全检查作为一个Aspect。

对我们来说非常好用。开发人员真的很喜欢关注点分离。架构师们真的很喜欢在一个位置上集中平台级别的逻辑。

PostSharp库是一个后编译器,它进行代码注入。它有一个预定义的拦截库,非常容易实现。感觉就像是连接事件处理程序一样简单。


1

我在我的C#应用程序中频繁使用AOP。我不太喜欢使用属性,因此我使用了Castle DynamicProxy和Boo,在运行时应用Aspect而不污染我的代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接