Aspect Oriented Programming在一个方面改变时是否需要重新编译?

huangapple go评论71阅读模式
英文:

Does Aspect Oriented Programming require recompilation whenever an aspect changes?

问题

一个重要的设计原则是OCP,它表明我们希望我们的模块能够开放进行扩展,但关闭进行修改。

当我们使用面向切面编程(AOP)时,会影响整个项目,这意味着切面的任何变化都可能改变项目中每个函数的行为。我想了解这是否意味着每次更改切面时都必须重新编译整个项目。这似乎与OCP相矛盾。如果不是这种情况,AOP编织是如何将行为添加到编译后的代码中的?

编辑:根据@kriegaex的评论,我特别关注Java和AspectJ。我正在教授软件设计,并将AOP作为使用框架来改善设计的示例。因为我教授SOLID设计原则,所以我想了解AOP对这些原则的影响。如果有任何不违反OCP的AOP框架(意味着更改切面不需要重新编译整个项目),请告诉我。

英文:

One important design principle is the OCP, which states that we would like our modules to be open for extension but closed to modification.

When we use Aspect Oriented Programming, we impact the whole project meaning that any change in an aspect may change the behavior of every function in the project. I wanted to understand if this implies that every time we change an aspect, we must recompile the whole project. This seems contradictory to the OCP. If this is not the case, how does the AOP weaving manage to add the behavior into the compiled code?

Edit: following the comment from @kriegaex, I am interested specifically in Java and with AspectJ.
I am teaching Software design and I give AOP as an example of using frameworks for better design. As I teach the SOLID design principles, I want to understand the impact of AOP on these principles.
If there is any AOP framework that does not violate OCP (meaning that changing an aspect does not require recompiling the whole project), please tell me about it.

答案1

得分: 2

使用场景

有多种情况:

载入时/运行时织入

  • 使用本机AspectJ进行载入时织入(LTW)在类加载过程中使用字节码工具。
  • Spring AOP在运行时创建动态代理,并将其连接到您的Spring bean中。

在这两种情况下,无需在更改切面后重新编译任何代码,因为所有切面织入都在运行时完成。您的原始字节码保持不变,但在应用程序启动时都有织入开销。织入后,AspectJ的性能与编译时或二进制(编译后)织入的切面完全相同。由于每次方法调用都会产生代理开销,Spring AOP始终较慢。

编译时织入(CTW)

在编译切面和应用程序代码时使用AspectJ编译器时,每次切面更改都需要重新编译核心代码,因为切面可能会影响任意数量的目标类。但优点是,无需设置像LTW那样的织入代理,也没有应用程序启动延迟。

二进制,编译后织入

这与CTW类似,但用于织入现有的类文件,例如,从第三方库中织入而不使用LTW。这将修改现有的字节码,您可能需要用包含织入类的新打包的JAR文件替换现有的JAR文件。

软件工程视角

在这些场景中,清晰地模块化和封装横切关注点,减少核心源代码的分散和交织,远远超过了您可能想要避免的传统OOP中的任何影响,比如OCP。在我看来,在这里你并没有真正违反OCP,因为你并没有修改核心类本身,而是用额外的行为装饰它们,这在一个切面内得到了清晰的模块化。可以将其称为装饰器模式的强化版,即无需在OOP中需要的所有典礼和样板。对我来说,AOP是一种工具,通过在纯粹的OOP中无法使用的方式来支持清晰的代码和更好的应用程序设计,而无需诉诸像多继承这样的噩梦般的东西。

英文:

Usage scenarios

There are multiple cases:

Load-time / run-time weaving

  • Native AspectJ with load-time weaving (LTW) uses byte code instrumentation during class-loading.
  • Spring AOP creates dynamic proxies wired into your Spring beans at runtime.

In both cases, there is no need to recompile any code after you change your aspects, because all aspect weaving is done during runtime. Your original bytecode stays intact, but you have the weaving overhead during application start for both options. After weaving, AspectJ performs exactly like compile-time or binary (post-compile) woven aspects. Spring AOP will always be slower due to the proxying overhead for every method call.

Compile-time weaving (CTW)

When using the AspectJ compiler when compiling your aspect and application code, every aspect change requires core code recompilation, because an aspect can potentially affect any number of target classes. The advantage however is that you do not need to set up any weaving agents like for LTW and there is no application start-up penalty.

Binary, post-compile weaving

This is similar to CTW, but used if you want to weave existing class files, e.g. from third-party libraries without resort to LTW. This will modify your existing byte code, and you might need to replace existing JARs by newly packaged ones containing the woven classes.

Software engineering perspective

In each of these scenarios, the advantages of cleanly modularising and encapsulating cross-cutting concerns and unburdening the core source code from scattering and tangling by far outweigh any effects which for classical OOP you might want to avoid, such as OCP. IMO, you do not really violate OCP here anyway, because you are not modifying the core classes as such, but rather decorating them with additional behaviours, which is cleanly modularised inside an aspect. Call it a Decorator pattern on steroids, i.e. without all the ceremony and boilerplate that you would need in OOP. For me, AOP is a tool supporting clean code and better application design by means unavailable in pure OOP, without the need to resort to nightmarish stuff like multiple inheritance.

huangapple
  • 本文由 发表于 2023年5月22日 19:12:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76305565.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定