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

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

问题描述

像这里和全世界的大多数开发人员一样,多年来,我一直在使用面向对象编程(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个(假设的),那么将其添加到任何地方都会变得非常痛苦.同样,无论何时添加新的设置方法,都必须确保不要忘记将其添加到最后,否则您只是创建了一个错误.

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 的方法,该类是包"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实际上正在做很多程序员认为" 反模式 ".确切的模式称为"远距离操作".

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.

作为项目的新手,我可能只是阅读任何设置方法的代码,并认为它已损坏,因为它似乎不会更新显示内容.我不会仅仅通过查看设置方法的代码来看到,而是在执行完设置方法的代码后,将神奇地"执行一些其他代码来更新显示.我认为这是一个严重的缺点!通过更改方法,可能会引入奇怪的错误.进一步理解某些似乎正确运行但不明显的代码流(如我所说,它们只是神奇地工作……以某种方式),确实很难.

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实际上是一个很棒的功能.我只是说小心使用".仅当您将相同的 Aspect 的常规代码和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天全站免登陆