Oop 面向方面编程与面向对象编程

Oop 面向方面编程与面向对象编程,oop,aop,paradigms,Oop,Aop,Paradigms,像这里和全世界的大多数开发人员一样,我多年来一直在使用面向对象编程(OOP)技术开发软件系统。所以当我读到面向方面编程(AOP)解决了许多传统OOP无法完全或直接解决的问题时,我停下来想,这是真的吗 我已经阅读了大量的信息,试图学习这个AOP范例的关键,我也处于同样的位置,因此,我想更好地了解它在实际应用程序开发中的好处 有人知道答案吗?OOP和AOP并不是相互排斥的。 AOP可以是OOP的良好补充。 AOP特别适合将标准代码(如日志记录、性能跟踪等)添加到方法中,而不会用此标准代码阻塞方法代码

像这里和全世界的大多数开发人员一样,我多年来一直在使用面向对象编程(OOP)技术开发软件系统。所以当我读到面向方面编程(AOP)解决了许多传统OOP无法完全或直接解决的问题时,我停下来想,这是真的吗

我已经阅读了大量的信息,试图学习这个AOP范例的关键,我也处于同样的位置,因此,我想更好地了解它在实际应用程序开发中的好处


有人知道答案吗?

OOP和AOP并不是相互排斥的。 AOP可以是OOP的良好补充。
AOP特别适合将标准代码(如日志记录、性能跟踪等)添加到方法中,而不会用此标准代码阻塞方法代码。

面向方面编程提供了一种很好的方法来实现横切关注点(如日志记录、安全性)。 这些交叉关注点是必须在许多地方应用的逻辑片段,但实际上与业务逻辑无关

您不应该将AOP视为OOP的替代品,而应该将其视为一个不错的附加组件 使您的代码更加干净、松散耦合,并专注于业务逻辑

因此,通过应用AOP,您将获得两大好处:

  • 每个关注点的逻辑现在都在一个地方,而不是分散在整个代码库中

  • 类更干净,因为它们只包含主要关注点(或核心功能)的代码,次要关注点已转移到方面


  • 我认为这个问题没有一般性的答案,但需要注意的是,AOP并没有取代OOP,而是添加了某些分解特性,以解决所谓的主导组合(或横切关注点)的暴政

    在某些情况下,只要您能够控制用于特定项目的工具和语言,它肯定会有所帮助,但同时也会增加方面交互的新复杂性,以及对其他工具(如)的需要,以便仍能理解您的程序


    Gregor Kiczales曾在谷歌技术讲座上就AOP做过一次有趣的介绍性演讲,我建议大家观看:。

    首先,AOP不会取代OOP。AOP扩展了OOP。OOP的思想和实践始终是相关的。拥有一个好的对象设计可能会更容易用方面来扩展它

    我认为AOP带来的想法很重要。我们需要找出方法,在不改变类本身的情况下,对程序中的不同类实现交叉关注点。但我认为AOP最终将成为我们使用的其他工具的一部分,而不是一个单独的工具或技术。我们已经看到了这种情况

    Ruby和Python等两种动态语言都有类似于mixin的语言结构,可以解决相同的问题。这看起来很像AOP,但更好地集成到语言中

    Spring和Castle以及其他两个依赖注入框架都有向它们注入的类添加行为的选项。这是一种运行时编织的方法,我认为这有很大的潜力

    我不认为你需要学习一个全新的范例来使用AOP。这些想法很有趣,但正在慢慢被现有的工具和语言吸收。请随时了解情况并试用这些工具。

    为什么选择“vs”?它不是“vs”。您可以将面向方面编程与函数式编程结合使用,也可以与面向对象编程结合使用。它不是“vs”,而是“面向方面编程与面向对象编程”

    对我来说,AOP是某种“元编程”。AOP所做的一切都可以在没有它的情况下通过添加更多代码来完成。AOP只是让你省去了编写这段代码

    Wikipedia是这种元编程的最好例子之一。假设您有一个包含许多“set…()”方法的图形类。在每个设置方法之后,图形的数据发生了变化,因此图形发生了变化,因此需要在屏幕上更新图形。假设要重新绘制图形,必须调用“Display.update()”。经典的方法是通过添加更多的代码来解决这个问题。在您编写的每个集合方法的末尾

    void set...(...) {
        :
        :
        Display.update();
    }
    
    如果您有3个set方法,那么这不是问题。如果你有200个(假设的),在任何地方添加这个都会让你感到非常痛苦。此外,无论何时添加新的set方法,都必须确保不要忘记将其添加到末尾,否则只会创建一个bug

    AOP在不添加大量代码的情况下解决了这一问题,而是添加了一个方面:

    after() : set() {
       Display.update();
    }
    
    就这样!与自己编写更新代码不同,您只需告诉系统,在达到set()切入点后,它必须运行此代码,并将运行此代码。无需更新200个方法,无需确保您不会忘记在新的set方法上添加此代码。此外,您只需要一个切入点:

    pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);
    
    这是什么意思?这意味着,如果一个方法名为“set*”(*表示set后面可能有任何名称),无论该方法返回什么(第一个星号)或它接受什么参数(第三个星号),并且它是MyGraphicsClass的方法,并且该类是包“com.company.*”的一部分,那么这就是set()切入点。我们的第一个代码是“在运行了任何一个设置切入点的方法之后,运行下面的代码”

    看看AOP如何优雅地解决这个问题?实际上,这里描述的一切都可以在编译时完成。AOP预处理器甚至可以在编译类本身之前修改源代码(例如,将Display.update()添加到每个set pointcut方法的末尾)

    然而,这个例子也显示了AOP的一大缺点。AOP实际上正在做许多程序员认为“<强> <强>”的事情。确切的模式称为“”

    远距离的行动是一种挑战 反模式(一种公认的常见模式) (错误)