Aspektorientierte Programmierung verspricht, sich mit Querschnittsthemen zu befassen, aber ich bin noch nicht vollständig davon überzeugt. Gab es andere Versuche, dieses Problem zu lösen?
Aspektorientierte Programmierung verspricht, sich mit Querschnittsthemen zu befassen, aber ich bin noch nicht vollständig davon überzeugt. Gab es andere Versuche, dieses Problem zu lösen?
Antworten:
Wenn möglich, können Sie Querschnittsthemen in separaten Modulen zusammenfassen, die dann über die Abhängigkeitsinjektion in der gesamten App verwendet werden. Auf diese Weise können Sie die Implementierung der Querschnittsanliegen ein wenig von ihrer Verwendung im gesamten Code entkoppeln.
Dies funktioniert jedoch nicht immer elegant. Das ist der Grund, warum Leute versuchen, das Problem mit Dingen wie AOP anzugehen.
Zwei weitere Optionen, die ich noch nicht erkundet habe:
Funktionale Programmierung mit Monaden und Pfeilen
In FP repräsentieren Sie ein Querschnittsthema wie alles andere: Sie übergeben es einem Funktionsaufruf. Da dies explizit mühsam wird, können Sie Monaden (oder Pfeile) verwenden, um die zusätzlichen Informationen, die weitergegeben werden, auszublenden.
Das häufigste AOP-Beispiel ist die Protokollierung. Mit Monaden würden Sie eine "Logger" -Monade erstellen, die eine Liste von Nachrichten enthält. Alle Funktionen, die Sie über LoggerMonad ausführen, können Protokollnachrichten veröffentlichen. Mit Arrows modellieren Sie den gesamten Datenfluss der Anwendung und arbeiten gegebenenfalls eine Protokollierungsroutine in das Modell ein. Ich glaube. Pfeile sind ziemlich komplex.
Entitäts- / komponentenbasierte Programmierung
Etwas, mit dem ich für eine Spiel-Engine geforscht und experimentiert habe. Anstelle von "Objekten" wie in OOP zerlegen Sie alles in Datenpakete (Komponenten) und Dienste, die über einen Komponententyp ausgeführt werden. Komponenten werden wie in einer relationalen Datenbank nach gemeinsamen IDs gruppiert, und Gruppen verknüpfter Komponenten sind die Entitäten. Um die Protokollierung in einem solchen System hinzuzufügen, fügen Sie einen neuen Protokollierungsdienst hinzu, dessen Trigger darauf basieren, welche Komponenten durchlaufen werden.
Beide Methoden ermöglichen es einem, einen Querschnittswechsel sehr einfach durchzuführen, aber beide sind Architekturmodelle auf hohem Niveau. Sie müssten sie also wahrscheinlich von Anfang an verwenden. Das Komponentenmodell kann theoretisch in ein bestehendes OOP-System eingearbeitet werden. Ich denke, Monaden könnten es auch sein, wenn Ihre Sprache mächtig genug ist.
Es gibt verschiedene Möglichkeiten, um die Probleme von Querschnittsproblemen anzugehen:
Bessere Entwurfsmuster, Redewendungen oder Abstraktionsmechanismen verwenden : Code kann übergreifend sein, obwohl er modularisiert werden kann. Um den Code zu verwalten, müssen Sie eine Umgestaltung durchführen, um die Entwurfstechnik zu verwenden, mit der er modularisiert werden kann. Ein solches Refactoring kann zu einer anderen Art von Querschnitten führen, aber hoffentlich ist es stabil, welche Querschnitte sich wahrscheinlich nicht ändern.
Reichhaltigere Sprachfunktionen entwickeln : Viele Manifestationen von Crosscutting können durch bessere Abstraktionsmechanismen gelöst werden, und manchmal sind neue Sprachfunktionen erforderlich. Beispielsweise verwenden fortgeschrittenere Sprachen, die funktionale und objektorientierte Merkmale enthalten, häufig nicht so viele Entwurfsmuster, weil sie nicht erforderlich sind. Beachten Sie, dass Entwurfsmuster selbst einen Querschnitt aufweisen können , da sie die Rollen mehrerer verschiedener Objekte und Klassen beschreiben. In Java kann Reflexion häufig anstelle eines Aspekts verwendet werden, obwohl dies zu höheren Laufzeitkosten führt. Mit Reflection können Sie beispielsweise das Besuchermuster über Hunderte von Klassen mit nur wenigen Codezeilen unterstützen. Die DJ-Bibliothekaus dem Nordosten ist eine reflektierende Lösung, die genau das tut. Mixins sind eine leistungsstarke Technik, die in C ++ (aber nicht in Java) verfügbar ist und Ihnen als Aspekt einige der gleichen Anwendungsfälle bieten kann.
Bessere Toolunterstützung : Techniken wie das Verwenden grep
und Ausführen von Refactoring-Vorgängen können Probleme im Zusammenhang mit dem Überschneiden von Code lösen. Beispielsweise kann der Name einer in einer Schnittstelle deklarierten Methode das Programm durchdringen. (Beachten Sie hier den technischen Unterschied: Es ist der Name der Methode, nicht die Implementierung der Methode, die sich überschneidet.) Dies ist normalerweise kein Problem in einer IDE wie Eclipse, in der Sie das "Refactoring umbenennen" verwenden können, um alle zu ändern die Stellen in Ihrem Code, die den Namen verwenden. Auf diese Weise ist es möglich, keine Sprachfunktionen zu benötigen, wenn die Programmierumgebung für Sie aussagekräftig genug ist.
Verwenden Sie domänenspezifische Sprachen : Die frühen Aspektsprachen, die vor AspectJ kamen, waren domänenspezifisch und wurden nur auf bestimmte Probleme angewendet, wie z. B. Thread-Synchronisation oder Datenflussanalyse, um Funktionszusammensetzungen effizient zu kombinieren. Diese Sprachen waren experimentell, schienen jedoch sehr erfolgreich darin zu sein, Probleme zu modularisieren, die ansonsten übergreifend waren.
Generative Programmiertechniken verwenden : Das Erreichen der Meta-Ebene kann als Implementierungstechnik für aspektorientierte Programmierung angesehen werden, ist aber groß genug, um über einfache Aspekte hinauszugehen. Generative Techniken (bei denen ein Programm Quellcode für ein anderes Programm generiert) beziehen sich auch auf domänenspezifische Sprachen.
Für all dies halte ich das Studium der AOP für angemessen. Mit AOP können Sie Ihre Codebegriffe erweitern, auch wenn Sie keine AOP-Sprache verwenden.
Im Allgemeinen werden Codeelemente mit einem deklarativen Merkmal gekennzeichnet, insbesondere jedoch das Attribut-System in der C # /. NET / Mono-Welt.
Ich bin kein Experte für AOP, aber seit ich es über die Jahre gelesen habe, schien es immer eine schwächere Form der von Lisp angebotenen Metaprogrammierung zu sein , insbesondere Teile wie das Metaobjektprotokoll.
Das sollte wohl nicht überraschen: Gregor Kiczales war einer der Autoren von AMOP und schrieb später AspectJ für Java!