【问题标题】:AOP... Should I unlearn OOP?AOP...我应该忘记 OOP 吗?
【发布时间】:2010-11-22 11:04:31
【问题描述】:

我浏览了在线文档,阅读了 wiki 条目、帖子和博客,但我仍然感到困惑。

  • 简而言之,面向方面的编程是什么?
  • 它是否比面向对象编程更好?我应该忘记 OOP 吗?
  • 如果不是,我怎么知道何时使用其中一种?两者的主要区别是什么?
  • 我可以将一个重构为另一个吗?

我一直是个 OO 人,我想知道我是否需要犯下叛国罪。

说真的,我很快就要开始一个新项目,我想从一开始就做出正确的选择。

【问题讨论】:

  • 锤子比​​螺丝刀好吗?取决于您要构建的内容。
  • 我将建造一些大的东西,有很多零件。我不(也不能)详细说明。但我真的很想了解更多关于 AOP 的总体情况。
  • 您是否也“浏览”了谷歌? lmgtfy.com/?q=AOP+vs+OOP
  • 另外,请看这个问题:stackoverflow.com/questions/232884/…
  • AOP 特别适合包含许多组件的大型项目。它在较小的项目中也很有价值(出于稍微不同的原因)。我们在大型金融服务平台上大量使用 OOP 和 AOP,发现如果您对何时使用(何时不使用)有很好的了解,它可以极大地简化大型系统的构建和操作。

标签: oop aop paradigms


【解决方案1】:

简而言之,什么是面向方面的编程?

简而言之,AOP 是一种将动作注入到另一个程序的典型流程中的能力,不显眼。它可以让您捕获类实例化、方法调用、分配等。

比面向对象编程更好吗?我应该忘记 OOP 吗?

没有,也没有。它与任何支持它的编程环境一起工作。 (见上文)。

如果不是,我怎么知道何时使用其中一种?两者的主要区别是什么?

通常,当您想在数百个类上实现某种动作时,您会使用 AOP,而不需要对这些类本身进行操作。典型的例子是安全性(授权调用给定方法/类的权利)或日志记录。但是,根据我的经验,我不会为此使用它。 (老实说,我根本不使用它)。

如上所述,主要区别并不存在,因为它们不具有可比性。但是,假设您想“正常”实现日志记录,您只需在适当的位置调用记录器:

log.write("hello");

但是使用 AOP,您可以创建一个附加到每个方法调用的“方面”,并记录“方法 b 调用”。关键是在 AOP 中,你的方法更像是“猎枪”:你附加到所有东西,或者只是一个小子集。手动添加日志记录通常更好。

我可以将一个重构为另一个吗?

不太相关,请参阅其他答案。再次考虑安全性,您可以从典型的 OOP 模型 this.IsAllowed() 切换到 AOP 模型,例如 if(callingMethod.HasAttribute(foo)){ allowed = true; }

希望这些答案有用。如果您希望我进一步扩展,请告诉我。

【讨论】:

  • 为什么不重构为 AOP?不过,我确实喜欢您的回答,考虑到四个问题,我认为您的回答非常简短,而且非常清楚。
  • 如果您已经有一个很好的 OOP 模型来实现某些东西,那么您通常不会需要将其更改为 AOP,因为它已经实现了! :) 当然,您可以将现有的安全机制换成 AOP 机制,我想(正如我试图概述的那样)。
  • 现在,我还没有完全喝下 AOP Kool-Aid,但是如果没有任何支持,你就不能发表诸如“手动添加日志记录通常更好”之类的声明 :) 我发现AOP 日志记录要干净得多,但我不是在处理大型企业级的东西。
  • Lewisham:我试图概述原因。原因是使用 AOP 日志记录,您最终会得到关于“一般”事物的语句,例如方法调用、增量等。如果您手动添加日志记录,您可以编写相关信息,仅显示感兴趣的变量,等等。 AOP 日志记录可能会有所帮助,并且很有用,但是手动执行它总是会让您提供那些对调试至关重要的小细节:)
  • 啊,我明白你的意思了。正如你所说,我使用“手动”AOP 日志记录,但我这样做是为了从核心逻辑中清除日志记录。工作量是相似的。
【解决方案2】:

AOP 与 OOP 不同,开发方法完全不同。

基本上,如果您有日志记录、身份验证问题、性能检查代码,这些代码在程序的各个部分、不同的类中大致相同。因此,您可以按照您的设想,用 Java 编写应用程序,然后当您需要添加这些其他类型的代码(横切关注点)时,您只需将它们注入程序中,以便可以编译它们,但是当你看源代码,你就看到了你需要的业务逻辑。

至于何时使用 AOP 或 OOP,我建议你编写程序,让它运行,然后当你运行它时,看看删除实际上与函数无关的代码,但提供一些其他目的。例如,如果您需要在使用输入参数之前检查它们是否正确,则为此使用方面。如果您有类似的事件处理,例如数据访问层中抛出的所有异常都写入日志文件,则为此创建一个方面。

当您消除这些横切关注点时,您的代码会变得更小。

随着您获得更多经验,您会看到 AOP 的更多用途,但最初我建议您编写它,然后使用 AOP 重构。

对于 AOP,如果使用 Java,则使用 E​​clipse,因为 AJDT 插件对于查看您在哪里添加方面非常有用。

【讨论】:

    【解决方案3】:

    不,AOP 是 OOP 的补充,而不是取代它。 AOP 和 OOP 提供了不同种类的“粘合剂”来​​帮助您组合行为。当然,OOP 允许您通过继承和组合等组合行为。另一方面,AOP 允许您通过拦截 point cuts 来添加行为到地址 cross cutting concerns,其中您的新代码在所选类的所选方法之前或之后运行.

    横切关注点的一些常见示例包括:安全性、日志记录和事务控制。良好设计的基本原则是连贯性:理想情况下,一段代码应该只做一件事。因此,例如,将安全代码添加到数据访问类中会搅浑水。 AOP 通过让您在“方面”中添加行为,然后将该方面应用于应该具有安全控制的所有类来解决该特定问题。

    【讨论】:

    • +1 指出 OOP 和 AOP 可以很好地协同工作
    【解决方案4】:
    【解决方案5】:

    面向方面的编程是一个吸引人的流行语,用于在调用和返回等关键点将操作(称为“建议”)插入方法或函数中。我对 AOP 有一个大问题,因为它违反了语言中内置的所有抽象障碍。模块无法说“这是一个方面可以解决的问题,而这是一个方面不能解决的问题。”因此,您可能会违反内部不变量,并且破坏了模块化推理的原则(您可以理解一个模块,而无需理解它所导入的其他模块的接口)。

    几年前,Raymie Stata 写了一篇精彩的博士论文,关于面向对象语言如何控制子类化 并防止它违反关键不变量。 AOP 的相应工作尚未编写。

    虽然与任何其他获得流行的想法一样,AOP 已经取得了一些惊人的成功(例如,将日志记录改进到未设计为考虑日志记录的应用程序),总的来说,我会敦促您限制您的使用AOP 到非常简单的情况。或者更好的是,对面向方面的编程说不。

    【讨论】:

    • 我喜欢你的思维方式。任何人都可以对此发表评论吗?我很感兴趣。
    • 我同意你的看法。 AOP的使用需要提前设计好,只限于选定的情况,而不是作为编程的一般原则,以避免它内在的“GOTOness”。
    • 我认为“抽象障碍”是指封装。 Grady Booch 将封装定义为“划分构成其结构和行为的抽象元素的过程;封装用于分离抽象的合同接口及其实现。” AOP 不会混淆接口和实现之间的水,因此根据 Grady Booch 的说法,它不会破坏封装。
    猜你喜欢
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多