Werden bestimmte Probleme mit AOP eleganter gelöst?

19

Ich bin auf die Idee der aspektorientierten Programmierung gestoßen und habe einige Bedenken.

Die Grundidee scheint zu sein, dass wir Querschnittsthemen, die mit object nicht gut modularisiert sind, aufnehmen und modularisieren wollen. Das ist alles sehr schön und gut.

Die Implementierung von AOP scheint jedoch darin zu bestehen, Code von außerhalb des Moduls zu ändern. So könnte beispielsweise ein Aspekt geschrieben werden, der ändert, was passiert, wenn ein bestimmtes Objekt als Parameter in einer Funktion übergeben wird. Dies scheint der Idee der Module direkt zu widersprechen. Ich sollte nicht in der Lage sein, das Verhalten eines Moduls von außerhalb dieses Moduls zu ändern, da sonst der gesamte Punkt der Module umgestürzt wird. Aber genau das scheinen die Aspekte zu tun!

Grundsätzlich scheinen Aspekte eine Form von Code-Patches zu sein. Es kann für einige schnelle Hacks nützlich sein; Aber im Allgemeinen ist es vielleicht nicht das, was Sie tun möchten. Die aspektorientierte Programmierung scheint mir eine schlechte Praxis zu sein und sich zu einem allgemeinen Designprinzip zu entwickeln.

Ist AOP eine gute Praxis? Werden bestimmte Programmierprobleme mit AOP eleganter gelöst?

Winston Ewert
quelle
ahhh, der berühmte Affenbeet!
Muad'Dib
1
Ich habe die Frage bearbeitet, um ihren Ton zu verbessern, und habe dafür gestimmt, sie wieder zu öffnen.
Robert Harvey
Questio wurde auch in einer anderen Form hier erneut gefragt: programmers.stackexchange.com/questions/19344/…
Peter Boughton

Antworten:

19

Aspektorientierte Programmierung ermöglicht es, bestimmte Arten der Programmierung durchzuführen, die schwierig sind, ohne unnötig Code in Ihrer Anwendung oder Bibliothek zu verstreuen, der nicht mit den Hauptfunktionen Ihrer Software in Zusammenhang steht (z. B. Querschnittsthemen). Beispiele beinhalten:

  1. Protokollierung und Überwachung
  2. Leistungsüberprüfung
  3. Debugging und Tracing
  4. Funktion rückgängig machen
  5. Validierung von Ein- und Ausgängen
  6. Morphen des Verhaltens vorhandener Objekte
  7. Objektfilter
  8. Sicherheitsimplementierung
  9. Transaktionen verwalten

Indem Sie solche Querschnittsthemen auf einen einzelnen Teil der Anwendung beschränken und diese Features dann über Attribute, Abfangen von Methodenaufrufen oder dynamische Proxys im Code referenzieren, können Sie das Querschnittverhalten kapseln. Dies hat alle Vorteile (dh einen einzigen Änderungspunkt), die eine Kapselung an einer anderen Stelle in Ihrer Anwendung bieten würde.

Der entscheidende Punkt hierbei ist, dass AOP Verhalten kapselt, das 1) in der gesamten Anwendung verbreitet ist und 2) für die Hauptfunktionalität der Anwendung peripher ist.

Robert Harvey
quelle
7

Ich komme zu spät zum Spiel, aber ich biete dies für spätere Entwickler, die über diese Frage stolpern könnten.

Ich rate dringend von AOP ab, wenn Ihre Anwendung davon abhängt, dass sie ordnungsgemäß funktioniert. Aspekte funktionieren so:

  • Beratung (zusätzliches Verhalten) wird angewendet auf
  • Verknüpfungspunkte (Stellen, an denen der zusätzliche Code angehängt werden kann, ein solcher Methodenbeginn oder -ende oder wenn ein bestimmtes Ereignis ausgelöst wird)
  • ... wo Pointcut- Muster (ein Muster, das erkennt, ob ein bestimmter Join-Punkt übereinstimmt) übereinstimmen

Für alle, die schon seit langer Zeit Computer benutzen, ist die Tatsache, dass Muster verwendet werden, möglicherweise etwas, das man genau betrachten sollte. Hier ist ein Beispiel für einen Pointcut, der mit jeder benannten Methode übereinstimmt, setunabhängig von den Argumenten:

call(* set(..))

Das ist also ein ziemlich weitreichender Punkt, und es sollte klar sein, dass es ratsam ist, vorsichtig damit umzugehen (kein Wortspiel beabsichtigt), da Sie Ratschläge auf viele Dinge anwenden.

Oder wie auch immer, lassen Sie uns auf alles hinweisen, unabhängig von Name oder Unterschrift!

execution(* *(..))

Wir sollten also vorsichtig sein, da hier viel Power steckt, aber dies ist kein Argument gegen Aspekte - es ist ein Argument zur Vorsicht, da hier viel Power steckt und der Mustervergleich leicht schief gehen kann (schlagen Sie einfach Ihre Lieblingssuchmaschine nach aop bugs und viel spaß

So sieht also ein relativ sicherer Pointcut aus:

pointcut setter(): target(Point) &&
                   ( call(void setX(int)) ||
                     call(void setY(int)) );

Dies gibt explizit Hinweise, ob Methoden mit Namen setXoder setYfür ein PointObjekt gefunden werden. Die Methoden können nur ints empfangen und müssen es auch sein void. Sieht ziemlich sicher aus, oder? Nun, das ist sicher, wenn diese Methoden existieren und Sie den richtigen Rat angewendet haben. Wenn nicht, schade; es versagt stillschweigend.

Ein Freund hat zum Beispiel versucht, eine Java-Anwendung zu debuggen, bei der alle ab und zu falsche Daten zurückgaben. Es war ein seltener Fehler und schien nicht mit einem bestimmten Ereignis oder Daten im Besonderen korreliert zu sein. Es war ein Threading-Fehler, der bekanntermaßen schwer zu testen oder zu erkennen ist. Es stellte sich heraus, dass sie Aspekte verwendeten, um Methoden zu sperren und sie "threadsicher" zu machen, aber ein Programmierer, der eine Methode umbenannte und einen Pointcut nicht übereinstimmte, verursachte einen unbeaufsichtigten Bruch der Anwendung.

Daher sage ich den Leuten, wenn sie AOP verwenden müssen, um Aspekte wie Ausnahmen zu behandeln: In einem gut konzipierten System können sie entfernt werden, und die Software funktioniert weiterhin ordnungsgemäß. Wenn die Funktionalität des Programms jedoch von AOP abhängt, führen Sie eine ungerechtfertigte Fragilität in Ihr Programm ein.

Protokollierung, Debugging und Tracing sind daher hervorragende Beispiele für Verhaltensweisen, die in Bezug auf Aspekte, aber auch auf die Sicherheit perfekt sind. Nee. Fadensicherheit? Nee.

Eine robuste Alternative zu AOP finden Sie unter Eigenschaften . Anstatt an die Sprache gebunden zu sein, werden sie direkt in die Sprache integriert, benötigen keine "trait aware" IDE (obwohl dies hilfreich sein kann) und weisen Kompilierungsfehler auf, wenn die von Ihnen benötigten Methoden nicht vorhanden sind. Traits erledigen die Trennung von Anliegen viel sauberer, da das Problem von Anfang an besser definiert wurde. Ich benutze sie ausgiebig und sie sind fantastisch.

Curtis Poe
quelle
Anstatt zu argumentieren, dass AOP nicht für die Kernfunktionalität verwendet werden sollte, ist es möglicherweise sinnvoller zu sagen, dass Pointcuts, die auf Methodennamen basieren, eine schlechte Idee sind. Ich würde wahrscheinlich argumentieren, dass Sperren und Synchronisieren auch für AOP keine guten Anwendungsfälle sind.
Code Bling
2

Eine Situation, in der AOP die einzig vernünftige und praktikable Lösung sein könnte, ist, wenn Sie keinen Zugriff auf den Quellcode haben . So verwenden Sie das müde alte Beispiel für das Querschnittsthema Protokollierung:

Angenommen, Sie möchten den Kontrollfluss in einer von Ihnen verwendeten Bibliothek eines Drittanbieters protokollieren. Sie haben Ihren eigenen Code, der vollständig mit Protokollanweisungen ausgestattet ist. Da Sie für diese Bibliothek jedoch nicht über die Quelle verfügen, können Sie Ihre Protokollierungsanweisungen nicht hinzufügen. Da Sie tun den Bytecode haben, können AOP Sie Instrument , dass Dritte Bibliothek sowieso.

Und wenn Sie trotzdem einen Protokollierungsaspekt erstellen, können Sie das Protokollieren mit AOP auch in Ihrem eigenen Code implementieren.

Joseph Tanenbaum
quelle
Protokollierung ist für "interessante" Dinge. Wie können Sie andere Dinge tun, als "mit diesen Parametern eingeben" und "mit der AOP-Protokollierung beenden"?
@Thorbjorn: Protokollierung / Debugging / Tracing ist nur einer von vielen Funktionsbereichen, bei denen AOP helfen kann. Ich habe es als Beispiel genommen, um meinen Standpunkt zu veranschaulichen. Der Punkt, den ich versuche, ist, dass AOP Ihnen mehr Kontrolle über den Bytecode von Drittanbietern gibt.
Joseph Tanenbaum
sicher, aber ich wollte wirklich wissen, ob die AOP-Protokollierung mehr kann als nur die Eingabe-Ausgabe-Protokollierung?
Dies hängt von dem von Ihnen verwendeten AOP-Tool ab, aber Ihre Möglichkeiten sind mit Sicherheit begrenzt. Möglicherweise ist es unmöglich, über die Eingabe- / Ausgabe-Protokollierung hinauszugehen.
Joseph Tanenbaum