和大多数开发人员一样,我在这里和整个世界上都使用面向对象编程(OOP)技术开发软件系统多年。因此,当我读到面向切面编程(AOP)可以解决传统OOP无法完全或直接解决的许多问题时,我会停下来思考,这是真的吗?
我阅读了很多信息,试图学习这种AOP范式的关键,并且我仍然处于同一位置,因此,我想更好地了解它在现实世界应用开发中的好处。
有人有答案吗?
和大多数开发人员一样,我在这里和整个世界上都使用面向对象编程(OOP)技术开发软件系统多年。因此,当我读到面向切面编程(AOP)可以解决传统OOP无法完全或直接解决的许多问题时,我会停下来思考,这是真的吗?
我阅读了很多信息,试图学习这种AOP范式的关键,并且我仍然处于同一位置,因此,我想更好地了解它在现实世界应用开发中的好处。
有人有答案吗?
void set...(...) {
:
:
Display.update();
}
after() : set() {
Display.update();
}
就是这样!你不需要自己编写更新代码,只需告诉系统在达到set()切入点后,必须运行此代码,它就会运行此代码。无需更新200个方法,也无需确保在新的set方法中不要忘记添加此代码。此外,您只需要一个切入点:
pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);
作为一个项目的新手,我可能会读任何set-method的代码并认为它已经损坏了,因为它似乎没有更新显示。通过查看set-method的代码,我看不到在执行后,将“神奇地”执行其他代码以更新显示。我认为这是一个严重的缺点!通过更改方法,可能会引入奇怪的错误。进一步理解代码流程,在某些东西似乎正常工作但不明显(就像我说的那样,它们只是以某种方式神奇地工作...),真的很难。远程操作是一个反模式(一个公认的常见错误),其中程序的某一部分的行为会根据另一部分的难以或不可能识别的操作而大幅度变化。
因此,在我的示例中,AOP的良好用法是始终记录是否通过set方法更新了任何值。这不会创建反模式,也几乎不会导致任何问题。
有人可能会说,如果您可以轻松滥用AOP来创建如此多的问题,那么使用它是一个坏主意。然而,哪种技术不能被滥用?您可以滥用数据封装,您可以滥用继承。几乎每个有用的编程技术都可能被滥用。考虑一种编程语言,它非常有限,只包含无法被滥用的功能;一种只能按照最初设计的方式使用功能的语言。这种语言非常有限,甚至可以争论它是否能用于实际编程。
面向切面编程提供了一种不错的方式来实现跨越多个领域的关注点,如记录日志和安全性。
这些关注点是逻辑片段,需要在许多地方应用,但实际上与业务逻辑没有任何关系。
您不应将AOP视为OOP的替代品,而应该将其视为一个不错的附加组件,可以使您的代码更加清晰、松耦合并专注于业务逻辑。
因此,通过应用AOP,您将获得两个主要优点:
每个关注点的逻辑现在都在一个地方,而不是分散在整个代码库中。
类更加清洁,因为它们只包含主要关注点(或核心功能)的代码,次要关注点已移动到切面中。
OOP和AOP并不是互相排斥的。 将AOP添加到OOP中可能是一个很好的补充。 AOP非常方便地为方法添加标准代码,例如记录日志、跟踪性能等,而无需将这些标准代码混杂在方法代码中。
我认为这个问题没有普遍的答案,但需要注意的一点是,AOP并不是取代OOP,而是添加了某些分解功能,解决了所谓的“主导组合的暴政”(或横切关注点) (1)。
只要你掌控特定项目使用的工具和语言,并且理解方面之间相互作用以及需要额外工具(如AJDT)来理解程序,它肯定在某些情况下有所帮助,但也增加了新的复杂性。
Gregor Kiczales曾在Google Tech Talks上发表过一次有趣的AOP简介演讲,我建议您观看:Aspect Oriented Programming: Radical Research in Modularity。
OOP主要用于组织您的业务逻辑,而AOP则有助于组织非功能性事物,例如审核、日志记录、事务管理、安全等。
通过这种方式,您可以将业务逻辑与非功能性逻辑解耦,使代码更加清晰。
另一个优点是,您可以非常一致地应用建议(如审核),而无需实现任何接口,这为修改提供了极大的灵活性,而不会触及业务逻辑。
这样就容易实现关注点分离和单一职责。
此外,当仅解决业务问题时,很容易从一个框架(比如Spring)移植业务逻辑到其他地方。