面向方面编程与面向对象编程 [英] Aspect Oriented Programming vs. Object-Oriented Programming

查看:35
本文介绍了面向方面编程与面向对象编程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Like most developers here and in the entire world, I have been developing software systems using object-oriented programming (OOP) techniques for many years. So when I read that aspect-oriented programming (AOP) addresses many of the problems that traditional OOP doesn't solve completely or directly, I pause and think, is it real?

我已经阅读了大量信息,试图了解这种 AOP 范式的关键,但我也是如此,因此,我想更好地了解它在实际应用程序开发中的好处.

I have read a lot of information trying to learn the keys of this AOP paradigm and I´m in the same place, so, I wanted to better understand its benefits in real world application development.

有人有答案吗?

推荐答案

为什么是vs"?它不是vs".您可以将面向方面编程与函数式编程结合使用,也可以与面向对象编程结合使用.它不是vs",而是面向方面的编程面向对象的编程".

Why "vs"? It is not "vs". You can use Aspect Oriented programming in combination with functional programming, but also in combination with Object Oriented one. It is not "vs", it is "Aspect Oriented Programming with Object Oriented Programming".

对我来说,AOP 是某种元编程".AOP 所做的一切也可以在没有它的情况下通过添加更多代码来完成.AOP 只是让您无需编写此代码.

To me AOP is some kind of "meta-programming". Everything that AOP does could also be done without it by just adding more code. AOP just saves you writing this code.

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

Wikipedia has one of the best examples for this meta-programming. Assume you have a graphical class with many "set...()" methods. After each set method, the data of the graphics changed, thus the graphics changed and thus the graphics need to be updated on screen. Assume to repaint the graphics you must call "Display.update()". The classical approach is to solve this by adding more code. At the end of each set method you write

void set...(...) {
    :
    :
    Display.update();
}

如果您有 3 个设置方法,那不是问题.如果您有 200 个(假设的),那么在任何地方添加它会变得非常痛苦.另外每当你添加一个新的 set-method 时,你一定不要忘记把它添加到最后,否则你只是创建了一个错误.

If you have 3 set-methods, that is not a problem. If you have 200 (hypothetical), it's getting real painful to add this everywhere. Also whenever you add a new set-method, you must be sure to not forget adding this to the end, otherwise you just created a bug.

AOP 无需添加大量代码即可解决此问题,您只需添加一个方面:

AOP solves this without adding tons of code, instead you add an aspect:

after() : set() {
   Display.update();
}

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

And that's it! Instead of writing the update code yourself, you just tell the system that after a set() pointcut has been reached, it must run this code and it will run this code. No need to update 200 methods, no need to make sure you don't forget to add this code on a new set-method. Additionally you just need a pointcut:

pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);

这是什么意思?这意味着如果一个方法被命名为set*"(* 表示可以在 set 之后跟随任何名称),无论该方法返回什么(第一个星号)或它采用什么参数(第三个星号)它是 MyGraphicsClass 的方法em> 这个类是包com.company.*"的一部分,那么这是一个 set() 切入点.我们的第一个代码说运行任何设置切入点的方法后,运行以下代码".

What does that mean? That means if a method is named "set*" (* means any name might follow after set), regardless of what the method returns (first asterisk) or what parameters it takes (third asterisk) and it is a method of MyGraphicsClass and this class is part of the package "com.company.*", then this is a set() pointcut. And our first code says "after running any method that is a set pointcut, run the following code".

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

See how AOP elegantly solves the problem here? Actually everything described here can be done at compile time. A AOP preprocessor can just modify your source (e.g. adding Display.update() to the end of every set-pointcut method) before even compiling the class itself.

然而,这个例子也显示了 AOP 的一大缺点.AOP 实际上正在做许多程序员认为是Anti-Pattern".确切的模式称为远距离动作".

However, this example also shows one of the big downsides of AOP. AOP is actually doing something that many programmers consider an "Anti-Pattern". The exact pattern is called "Action at a distance".

远距离行动是一种反模式(公认的常见错误)在哪一个部分的行为一个程序的差异很大难以或不可能识别另一部分的操作程序.

Action at a distance is an anti-pattern (a recognized common error) in which behavior in one part of a program varies wildly based on difficult or impossible to identify operations in another part of the program.

作为一个项目的新手,我可能只是阅读了任何 set-method 的代码并认为它​​已损坏,因为它似乎没有更新显示.我不看到仅仅通过查看 set-method 的代码,在它被执行之后,其他一些代码会神奇地"被执行.执行以更新显示.我认为这是一个严重的缺点!通过对方法进行更改,可能会引入奇怪的错误.进一步理解代码的代码流,其中某些事情似乎可以正常工作,但并不明显(正如我所说,它们只是神奇地工作......不知何故),真的很难.

As a newbie to a project, I might just read the code of any set-method and consider it broken, as it seems to not update the display. I don't see by just looking at the code of a set-method, that after it is executed, some other code will "magically" be executed to update the display. I consider this a serious downside! By making changes to a method, strange bugs might be introduced. Further understanding the code flow of code where certain things seem to work correctly, but are not obvious (as I said, they just magically work... somehow), is really hard.

澄清一下:有些人可能觉得我说 AOP 是不好的东西,不应该使用.这不是我要说的!AOP 实际上是一个很棒的特性.我只是说小心使用".如果您将普通代码和 AOP 混合用于相同的方面,AOP 只会导致问题.在上面的例子中,我们有更新图形对象的值和绘制更新对象的方面.这实际上是一个方面.将它的一半编码为普通代码,将另一半编码为方面是增加问题的原因.

Just to clarify that: Some people might have the impression I'm saying AOP is something bad and should not be used. That's not what I'm saying! AOP is actually a great feature. I just say "Use it carefully". AOP will only cause problems if you mix up normal code and AOP for the same Aspect. In the example above, we have the Aspect of updating the values of a graphical object and painting the updated object. That is in fact a single aspect. Coding half of it as normal code and the other half of it as aspect is what adds the problem.

如果您将 AOP 用于完全不同的方面,例如对于日志记录,您不会遇到反模式问题.在这种情况下,项目的新手可能会想知道所有这些日志消息来自哪里?我在代码中没有看到任何日志输出",但这不是一个大问题.他对程序逻辑所做的更改几乎不会破坏日志设施,而对日志设施所做的更改几乎不会破坏他的程序逻辑——这些方面是完全分开的.使用 AOP 进行日志记录的优势在于,您的程序代码可以完全专注于做它应该做的任何事情,并且您仍然可以拥有复杂的日志记录,而不会让您的代码被数百条日志消息杂乱无章.此外,当引入新代码时,神奇的日志消息将在正确的时间以正确的内容出现.新手程序员可能不明白他们为什么在那里或他们来自哪里,但因为他们会记录正确的事情"在合适的时间",他可以愉快地接受他们在那里的事实,然后继续做其他事情.

If you use AOP for a completely different aspect, e.g. for logging, you will not run into the anti-pattern problem. In that case a newbie to the project might wonder "Where do all these log messages come from? I don't see any log output in the code", but that is not a huge problem. Changes he makes to the program logic will hardly break the log facility and changes made to the log facility will hardly break his program logic - these aspects are totally separated. Using AOP for logging has the advantage that your program code can fully concentrate on doing whatever it should do and you still can have sophisticated logging, without having your code being cluttered up by hundreds of log messages everywhere. Also when new code is introduced, magically log messages will appear at the right time with the right content. The newbie programmer might not understand why they are there or where they came from, but since they will log the "right thing" at the "right time", he can just happily accept the fact that they are there and move on to something else.

因此,在我的示例中,AOP 的一个很好的用法是始终记录是否通过 set 方法更新了任何值.这不会产生反模式,也几乎不会导致任何问题.

So a good usage of AOP in my example would be to always log if any value has been updated via a set method. This will not create an anti-pattern and hardly ever be the cause of any problem.

有人可能会说,如果您可以轻易地滥用 AOP 来制造如此多的问题,那么全部使用它是个坏主意.然而,哪些技术不能被滥用?你可以滥用数据封装,也可以滥用继承.几乎所有有用的编程技术都可能被滥用.考虑一种非常有限的编程语言,它只包含不能被滥用的功能;一种语言,其中功能只能按最初打算使用的方式使用.这样的语言非常有限,以至于它甚至可以用于现实世界的编程是有争议的.

One might say, if you can easily abuse AOP to create so many problems, it's a bad idea to use it all. However which technology can't be abused? You can abuse data encapsulation, you can abuse inheritance. Pretty much every useful programming technology can be abused. Consider a programming language so limited that it only contains features that can't be abused; a language where features can only be used as they were initially intended to be used. Such a language would be so limited that it's arguable if it can be even used for real world programming.

这篇关于面向方面编程与面向对象编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆