Scala: Java AspectJ um Ratgeber oder Python-Dekoratoren implementieren

7

Ich habe Java + AspectJ ausgiebig für mein Startup verwendet. Ich würde gerne zu Scala wechseln, aber ich habe ein gemeinsames Designmuster, von dem ich nicht ganz sicher bin, dass es der beste Weg ist, es in Scala umzusetzen.

Ein großer Teil unserer Anwendung verwendet AspectJ-Punkte mit Annotationen als Marker. Dies ist sehr ähnlich zu Pythons Dekorateur und hier darüber gebloggt .

Ich habe versucht, diese Technik in Scala zu machen, hatte aber Probleme mit AspectJ + Scala Selbst wenn ich es zur Arbeit bringen würde, scheint es UnScala zu sein.

Ich habe einige Projekte gesehen, die eine Call-by-Name Schließungsmagie machen (ich denke, das ist was sie tun).

Beispiel für eine Ersetzung von @Transaction:

%Vor%

Ich muss sagen, obwohl ich die Annotation lieber bevorzuge, da sie deklarativer erscheint. Wie kann Scala deklarativ Codeblöcke "dekorieren"?

    
Adam Gent 14.05.2011, 14:23
quelle

3 Antworten

12

Übrigens rede ich an den Scala Days 2011 zum gleichen Thema . Die Kernidee ist die gleiche wie die von Kim und Dean. Wenn es jedoch um das gesamte Spektrum von Querschnittsaufgaben geht, werden Ähnlichkeit und Unterschiede differenzierter.

An einem Ende des Spektrums gibt es keine wirklich überschneidenden Bedenken wie Caching. Wenn die Hostsprache keine Funktionen höherer Ordnung (z. B. Java) unterstützt, wird die Implementierung des Anliegens als Aspekt attraktiv. Zum Beispiel können Sie mit AspectJ und Annotation Ansatz sagen:

%Vor%

Aber mit höherer Funktion in Scala können Sie:

%Vor%

Der Scala-Ansatz ist viel besser, weil:

  • Caching ist unwahrscheinlich weit verbreitet. Zum Beispiel ist es unwahrscheinlich, dass alle Methoden in einer Klasse oder alle öffentlichen Methoden in allen Klassen in einem Paket zwischenspeicherbar sind. Und selbst wenn es eine solche Situation gibt, ist die keyScript wahrscheinlich nicht die gleiche oder einfach in einer generischen Form ausdrückbar.
  • Der AspectJ-Ansatz verwendet Annotation als Krücke, um eine anständige Implementierung anzubieten. Mit der Funktion höherer Ordnung in Scala wird die Absicht direkt ausgedrückt.
  • Der AspectJ-Ansatz muss eine externe Sprache (wie OGNL oder Spring Expression Language) verwenden, um den Schlüssel zu berechnen. Mit Scala können Sie einfach die Hostsprache verwenden.

In der Mitte gibt es häufig Querfaktoren, die das Transaktionsmanagement und die Sicherheit betreffen. Auf der Oberfläche sehen sie wie Caching aus. Wir finden jedoch in der Praxis, dass die Anwendung dieser Funktionalitäten auf alle Methoden einer Klasse (mit generischer Unterauswahl wie die mit öffentlichem Zugriff) oder alle Methoden aller Klassen, die mit einer Anmerkung markiert sind (zB @Service ) üblich ist. Wenn dies der Fall ist, ist der AspectJ-Ansatz besser, da er eine Möglichkeit bietet, die Funktionalität auf einer höheren Ebene anzuwenden, die Funktionen höherer Ordnung erfüllt. Sie müssen nicht mehr jede Methode mit transactional {} oder secured {} einbeziehen, wenn eine Annotation auf Klassenebene problemlos funktioniert. Bei sicherheitsrelevanten Problemen ermöglicht der AspectJ-Ansatz eine einfachere Durchführung von Sicherheitsüberprüfungen.

Am anderen Ende des Spektrums sind übergreifende Probleme wie Ablaufverfolgung, Profilerstellung, Überwachung, Richtliniendurchsetzung, Überwachung, einige Formen der Nebenläufigkeitskontrolle (wie Swing / SWT / Android UI Thread-Dispatching) usw. Diese eignen sich sehr gut, um mit einem Pointcut (mit und oft ohne Annotationen) ausgewählt zu werden. Es ist sehr schwierig, das Gleiche einheitlich mit Funktionen höherer Ordnung zu tun.

Es gibt mehr semantische Nuancen, aber die Quintessenz ist, dass, wenn Sie feststellen, dass jede Methode ein querschneidendes Problem anwendet, die Funktion höherer Ordnung wahrscheinlich ein besserer Ansatz ist. Für andere bietet die Verwendung von Scala mit AspectJ wahrscheinlich eine konsistente und kompakte Lösung.

ps. Ich habe AspectJ Scala in Eclipse in letzter Zeit nicht mehr ausprobiert (seit Scala in Eclipse erst vor kurzem angefangen hat). Aber externe Build mit Maven funktionierte gut nach Ссылка wurde behoben.

    
ramnivas 14.05.2011, 19:02
quelle
8

Der scala Weg wäre

%Vor%

Dies druckt

%Vor%     
Kim Stebel 14.05.2011 14:55
quelle
5

Es gibt weitere Vorteile bei der Verwendung des Ansatzes der Transaktionsmethode gegenüber Annotationen. Sie können Catch- und Finally-Klauseln hinzufügen, um eine ordnungsgemäße Ressourcenbereinigung sicherzustellen. Um Kims Beispiel etwas zu erweitern:

%Vor%

Sie können auch Transaktionen innerhalb von Methodenkörpern aufrufen, während Sie einen internen Block einer Methode nicht annotieren können. Natürlich könnten Sie diesen internen Block auch zu einem anderen Methodenaufruf mit einer Anmerkung machen.

Ich verstehe die Attraktivität von Annotationen und XML-Konfigurationsdateien aus meiner Java-Zeit, aber heutzutage bevorzuge ich es, alles als "normalen" Code zu schreiben, wegen der Einheitlichkeit und der größeren Ausdruckskraft. Ich verwende nur Anmerkungen, wenn ich eine Java-Bibliothek aufruft, die sie benötigt. Auch, wenn Sie Ihren Code so "funktional" wie möglich machen, dann ist alles deklarativ! ;)

    
Dean Wampler 14.05.2011 15:26
quelle

Tags und Links