Aspektorientierte Programmierung in C++ Sören Frey | Florian Walker Vortrag im Rahmen des Master Seminars HS Mannheim SS2006 Florian Walker | Sören Frey – HS Mannheim SS2006 1 Übersicht 1. Wiederholung AOP Grundlagen 2. Motivation – Warum AOP in C++ 3. Vorstellung des durchgängigen Szenarios 4. AOP mit reinem C++ 4.1 Präprozessor 4.2 Templates 4.3 Namensräume 4.4 Begrenzungen 4.5 Schlussfolgerungen 5. AOP mit AspectC++ 5.1 Überblick 5.2 Funktionsweise 5.3 Szenario in AspectC++ 5.4 Generisches Observer Pattern 5.5 Generierter Code 5.6 Toolsupport Folie 2 6. Weitere Ansätze 7. Zusammenfassung Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 2 1. AOP Grundlagen » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates Einordnung: Assembler Prozedurale Sprache (PASCAL, FORTRAN) » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ kuchen = backen(mehl, zucker, butter) » Überblick » Funktionsweise » Szenario » Observer Pattern OO-Sprachen (C++, JAVA) » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung kuchen = new Kuchen(mehl, eier, zucker); Kuchen.backe(); Aspektorientierte Sprachen (AspectJ, AspectC++) OOPS um Aspekte angereichert Folie 3 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 3 1. AOP Grundlagen » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Quelle: http://www.informatik.hs-mannheim.de/~knauber/MSc-MSI-06/index.htm Folie 4 Sören Frey | Florian Walker HS Mannheim SS2006 • Kernfunktionalitäten (eng. core concerns) können durch Objektorientierung sauber in Module getrennt werden. Es gibt jedoch Belange wie Sicherheit, Datenerfassung und Fehlerbehandlung in jedem System die die Kernfunktionalitäten quer schneiden (eng. crosscut) und sich deshalb nicht eindeutig in Softwaremodule zuordnen lassen. Dies führt zu einer Verstreuung der crosssutting concens über den gesamten Code einer Anwendung und beeinflusst so die Wiederverwendbarkeit, Wartung und Verständlichkeit. Florian Walker | Sören Frey – HS Mannheim SS2006 4 1. AOP Grundlagen - Begriffe » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ Joinpoint Wohldefinierter Punkt im Programmfluss » Präprozessor » Templates Können sein: Aufruf, Ausführung einer Methode, Zugriff auf Variable, Behandlung einer Exception … » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern Pointcut Die Auswahl eines oder mehrerer Joinpoints Bei erreichen des Pointcuts wird der Aspekt-Code ausgeführt » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 5 Menge aller Joinpoints Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 5 1. AOP Grundlagen - Begriffe » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor Advice Der Code des Aspekts » Templates Ausführung bei erreichen des Pointcuts » Namensräume » Begrenzungen Kann eingewebt werden: z.B. before, after, around » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern Introduction Erweiterung anderer Klassen, Interfaces um zusätzliche Funktionalität » Generierter Code Beispielsweise hinzufügen neuer Funktionen oder Attribute » Toolsupport » Weitere Ansätze » Zusammenfassung Aspect „Container für neue Konzepte“ können Advices und Pointcuts enthalten sowie Methoden und Variablen Folie 6 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 6 2. Motivation » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor Vorteile AOP Vermeidung von redundantem Code, bessere Wiederverwendbarkeit/Wartbarkeit, erhöhte Übersichtlichkeit … » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick Verbinden mit C++, da » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze Millionen Programmierer verwenden C++ Für viele Domänen die einzige sinnvolle Sprache (z.B. bei vielen eingebetteten Systemen) » Zusammenfassung Sehr viele Programme in C++ geschrieben wurden Verbesserung der Wartbarkeit (Erweiterungen) Folie 7 Sören Frey | Florian Walker HS Mannheim SS2006 • Verbesserung der Wartbarkeit da Erweiterungen oft die crosssutting concens sind. Florian Walker | Sören Frey – HS Mannheim SS2006 7 3. Das Szenario » AOP Grundlagen » Motivation » Das Szenario Anwendung: WordOOP » AOP mit reinem C++ » Präprozessor » Templates Einfache „Textverarbeitung“ » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario Funktionen Authentifikation über Benutzernamen/Passwort Texteingabe und anschließende Speicherung Gespeicherten Text laden und anzeigen » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze WordOOP » Zusammenfassung +authenticate(string& user_, string& passw_):bool +showMenueAndGetChoice():int +enterAndSaveNewText():void +loadAndDisplaySavedText():void +writeTextToFile(string& text, string& file):void +getTextFromFile(string& file):string +logout():void Folie 8 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 8 3. Das Szenario » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ WordOOP - Die einfache Anwendung #include "WordOOP.h" #include <fstream> void WordOOP::loadAndDisplaySavedText(){ string fileName; bool WordOOP::authenticate(string& user_, string& passw_){ » Präprozessor string user » Templates string passw = "MSI"; » Namensräume return user.compare(user_) == 0 && passw.compare(passw_) == 0; » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ cout << endl << "Enter file name: "; = "MSI"; cin cout << endl << "TEXT IN FILE IS: " << text << endl; } } void WordOOP::writeTextToFile(string& text, string& file){ int WordOOP::showMenueAndGetChoice(){ ofstream out; cout << endl » Überblick out.open(file.c_str()); << "1: Enter and save new text" » Funktionsweise << endl out << text; << "2: Load and display saved text" << endl » Szenario << "3: Exit" » Observer Pattern << endl << endl » Generierter Code out.close(); } string WordOOP::getTextFromFile(string& file){ << "Your choice: "; » Toolsupport char text[256]; int res; » Weitere Ansätze ifstream in; cin >> res; » Zusammenfassung >> fileName; string text = getTextFromFile(fileName); in.open(file.c_str()); return res; if(in.is_open()){ } in.getline(text, 256); void WordOOP::enterAndSaveNewText(){ in.close(); string fileName; return string(text); string text; } cout << endl << "Enter text: "; cin.ignore(); cout << "Enter new file name: "; cin else // Erase last "return getline(cin, text); return string("##ERROR WHILE OPENING FILE##"); } void WordOOP::logout(){ >> fileName; writeTextToFile(text, fileName); cout << "GOODBYE !" << endl; } } Folie 9 Sören Frey | Florian Walker HS Mannheim SS2006 • Inhalt der Implementierungsdatei WordOOP.cpp • Definition der Klasse • Fachlicher Code • Klassendeklaration in der Header-Datei WordOOP.h • Verwendung durch Anwendungscode (app.cpp) Florian Walker | Sören Frey – HS Mannheim SS2006 9 3. Das Szenario » AOP Grundlagen » Motivation » Das Szenario Typisches Problem: » AOP mit reinem C++ » Präprozessor » Templates Verschiedene Stakeholder fordern Erweiterungen von WordOOP » Namensräume » Begrenzungen Logging könnte nicht schaden » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario Word sollte die Arbeitszeit erfassen » Observer Pattern » Generierter Code Wir brauchen mehr Sicherheit! » Toolsupport » Weitere Ansätze $ $ » Zusammenfassung Folie 10 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 $ HS Mannheim SS2006 10 3. Das Szenario » AOP Grundlagen Die nicht mehr ganz einfache Anwendung WordOOP mit allen Aspekten #include "WordOOP.h" void WordOOP::writeTextToFile(string& text, string& file){ string WordOOP::getWorkTime(){ » Motivation #include <fstream> string workTime; ofstream out; » Das Szenario #include <sstream> time_t diff = endTime - startTime; out.open(file.c_str()); bool WordOOP::authenticate(string& user_, string& passw_){ int numOfHours; string user » AOP mit reinem C++ = "MSI"; int numOfMinutes; string passw = "MSI"; int numOfSeconds; if(user.compare(user_) == 0 » Templates numOfHours startTime = time(0); } else return false; in.getline(text, 256); string numString; } in.close(); ostringstream hourOutStream; int WordOOP::showMenueAndGetChoice(){ return string(text); ostringstream minuteOutStream; cout << endl » Funktionsweise << "3: Exit" } ostringstream secondOutStream; << endl else << "2: Load and display saved text" << endl return string("##ERROR WHILE OPENING FILE##"); if(numOfHours < 10) << endl workTime = "0"; << endl » Szenario } void WordOOP::setEndTime(time_t end){ << "Your choice: "; endTime = end; hourOutStream << numOfHours; int res; » Observer Pattern » Weitere Ansätze if(in.is_open()){ - numOfMinutes * 60; » Überblick » Toolsupport in.open(file.c_str()); numOfSeconds = diff - numOfHours * 3600 << "1: Enter and save new text" » Generierter Code ifstream in; (numOfHours * 3600)) / 60); return true; » Begrenzungen char text[256]; = (int) (diff / 3600); numOfMinutes = (int) ((diff – && passw.compare(passw_) == 0){ » Namensräume » AOP mit AspectC++ out.close(); string WordOOP::getTextFromFile(string& file){ » Präprozessor » Schlussfolgerungen out << text; } numString = hourOutStream.str(); cin >> res; } void WordOOP::loadAndDisplaySavedText(){ workTime += numString + "h"; return res; string fileName; } cout << endl << "Enter file name: "; if(numOfMinutes < 10) //Simple caesar-encryption if(text != "##ERROR WHILE OPENING FILE##") workTime += ":"; string::iterator iterator = textToEncrypt.begin(); cout << endl << "TEXT IN FILE IS: „ minuteOutStream << numOfMinutes; for(unsigned int i = 0; i < textToEncrypt.size(); i++){ << decryptText(text) << endl; numString = minuteOutStream.str(); encryptedText += (((char) *iterator) + 3); else workTime += numString + "m"; iterator++; >> fileName; string text = getTextFromFile(fileName); else string encryptedText; » Zusammenfassung cin workTime += ":0"; string WordOOP::encryptText(string& textToEncrypt){ cout << endl << "TEXT IN FILE IS: " << } text << endl; if(numOfSeconds < 10) return encryptedText; string message = "File " + fileName + " loaded"; workTime += ":0"; } else void WordOOP::enterAndSaveNewText(){ } workTime += ":"; string fileName; string text; string WordOOP::decryptText(string& textToDecrypt){ // Erase last "return" >> fileName; return workTime; logger.writeMessageToFile(message); for(unsigned int i = 0; i < textToDecrypt.size(); i++){ } decryptedText += (((char) *iterator) - 3); void WordOOP::logout(){ iterator++; cout << "GOODBYE !" << endl; writeTextToFile(encryptedText, fileName); string message = "File " + fileName + " saved"; string::iterator iterator = textToDecrypt.begin(); workTime += numString + "s"; cout << "Enter new file name: "; string encryptedText = encryptText(text); string decryptedText; numString = secondOutStream.str(); getline(cin, text); cin //Simple caesar-decryption secondOutStream << numOfSeconds; cout << endl << "Enter text: "; cin.ignore(); logger.writeMessageToFile(message); } } return decryptedText; } } Folie 11 Sören Frey | Florian Walker HS Mannheim SS2006 • Inhalt der Implementierungsdatei nach Realisierung aller geforderten Aspekte direkt in der Fachklasse. Florian Walker | Sören Frey – HS Mannheim SS2006 11 3. Das Szenario » AOP Grundlagen Welcher Code tut was? #include "WordOOP.h" void WordOOP::writeTextToFile(string& text, string& file){ string WordOOP::getWorkTime(){ » Motivation #include <fstream> string workTime; ofstream out; » Das Szenario #include <sstream> time_t diff = endTime - startTime; out.open(file.c_str()); bool WordOOP::authenticate(string& user_, string& passw_){ int numOfHours; string user » AOP mit reinem C++ = "MSI"; int numOfMinutes; string passw = "MSI"; int numOfSeconds; if(user.compare(user_) == 0 » Templates numOfHours startTime = time(0); } else return false; in.getline(text, 256); string numString; } in.close(); ostringstream hourOutStream; int WordOOP::showMenueAndGetChoice(){ return string(text); ostringstream minuteOutStream; cout << endl » Funktionsweise << "3: Exit" } ostringstream secondOutStream; << endl else << "2: Load and display saved text" << endl return string("##ERROR WHILE OPENING FILE##"); if(numOfHours < 10) << endl workTime = "0"; << endl » Szenario } void WordOOP::setEndTime(time_t end){ << "Your choice: "; endTime = end; hourOutStream << numOfHours; int res; » Observer Pattern » Weitere Ansätze if(in.is_open()){ - numOfMinutes * 60; » Überblick » Toolsupport in.open(file.c_str()); numOfSeconds = diff - numOfHours * 3600 << "1: Enter and save new text" » Generierter Code ifstream in; (numOfHours * 3600)) / 60); return true; » Begrenzungen char text[256]; = (int) (diff / 3600); numOfMinutes = (int) ((diff – && passw.compare(passw_) == 0){ » Namensräume » AOP mit AspectC++ out.close(); string WordOOP::getTextFromFile(string& file){ » Präprozessor » Schlussfolgerungen out << text; } numString = hourOutStream.str(); cin >> res; } void WordOOP::loadAndDisplaySavedText(){ workTime += numString + "h"; return res; string fileName; } cout << endl << "Enter file name: "; if(numOfMinutes < 10) //Simple caesar-encryption if(text != "##ERROR WHILE OPENING FILE##") workTime += ":"; string::iterator iterator = textToEncrypt.begin(); cout << endl << "TEXT IN FILE IS: „ minuteOutStream << numOfMinutes; for(unsigned int i = 0; i < textToEncrypt.size(); i++){ << decryptText(text) << endl; numString = minuteOutStream.str(); encryptedText += (((char) *iterator) + 3); else workTime += numString + "m"; iterator++; >> fileName; string text = getTextFromFile(fileName); else string encryptedText; » Zusammenfassung cin workTime += ":0"; string WordOOP::encryptText(string& textToEncrypt){ cout << endl << "TEXT IN FILE IS: " << } text << endl; if(numOfSeconds < 10) return encryptedText; string message = "File " + fileName + " loaded"; workTime += ":0"; } else void WordOOP::enterAndSaveNewText(){ } workTime += ":"; string fileName; string text; string WordOOP::decryptText(string& textToDecrypt){ // Erase last "return" >> fileName; return workTime; logger.writeMessageToFile(message); for(unsigned int i = 0; i < textToDecrypt.size(); i++){ } decryptedText += (((char) *iterator) - 3); void WordOOP::logout(){ iterator++; cout << "GOODBYE !" << endl; writeTextToFile(encryptedText, fileName); string message = "File " + fileName + " saved"; string::iterator iterator = textToDecrypt.begin(); workTime += numString + "s"; cout << "Enter new file name: "; string encryptedText = encryptText(text); string decryptedText; numString = secondOutStream.str(); getline(cin, text); cin //Simple caesar-decryption secondOutStream << numOfSeconds; cout << endl << "Enter text: "; cin.ignore(); logger.writeMessageToFile(message); } } return decryptedText; } } Folie 12 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 12 3. Das Szenario - Probleme » AOP Grundlagen » Motivation » Das Szenario Vermischung des Codes mit verschiedenen logisch getrennten Aspekten Code ist schwer zu schreiben » AOP mit reinem C++ » Präprozessor » Templates » Namensräume gleichzeitige Beachtung aller Aspekte » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick Code ist schwer zu lesen Weiterentwicklung und Wartung sind umständlich » Funktionsweise » Szenario » Observer Pattern Verschiedene Belange sind über den gesamten Code verstreut » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Skalierbarkeit ist schwer Anwender bekommt eine Klasse für alles Folie 13 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 13 4. AOP mit reinem C++ » AOP Grundlagen » Motivation » Das Szenario Überblick » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick Erweiterung des vorgestellten Beispiels um verschiedene Aspekte Sicherheit – Verschlüsselung der Textdateien Arbeitszeiterfassung Protokollierung der Dateizugriffe » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Umsetzung verschiedener AOP Konzepte mittels Präprozessor Templates Namensräumen Ziel: Vorteile und Beschränkungen von reinem C++ aufzeigen Notwendigkeit von Spracherweiterungen einschätzen Folie 14 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 14 4.1 Präprozessor » AOP Grundlagen //WordOOP.h » Motivation #define SECURITY_ASPECT » Das Szenario #define LOGGING_ASPECT » AOP mit reinem C++ #define WORKTIME_ASPECT #ifdef WORKTIME_ASPECT void setEndTime(time_t end); string getWorkTime(); » Präprozessor #endif » Templates #ifdef WORKTIME_ASPECT » Namensräume #include "time.h" » Begrenzungen #endif » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung virtual void writeTextToFile( string& text, string& file); virtual string getTextFromFile( string& file); #ifdef LOGGING_ASPECT void logout(); #include "Logger.h" private: #endif #ifdef SECURITY_ASPECT using namespace std; string encryptText(string& textToEncrypt); class WordOOP { string decryptText(string& textToDecrypt); public: WordOOP(); #endif virtual ~WordOOP(); #ifdef WORKTIME_ASPECT time_t startTime; bool authenticate(string& user_, time_t endTime; string& passw_); int showMenueAndGetChoice(); #endif void enterAndSaveNewText(); #ifdef LOGGING_ASPECT Logger logger; void loadAndDisplaySavedText(); #endif }; //class WordOOP Folie 15 Sören Frey | Florian Walker HS Mannheim SS2006 • Der Präprozessor führt Änderungen am Quellcode durch, bevor der eigentliche Compiler das Programm übersetzt. • #ifdef, #endif ermöglichen die bedingte Übersetzung bestimmter Programmteile Ù „compile-time-Schalter“ • Häufige Anwendung: Konfiguration von Debug-Code Florian Walker | Sören Frey – HS Mannheim SS2006 15 4.1 Präprozessor » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ Vorteil: + Funktionen können aktiviert/deaktiviert werden » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick Nachteile: - Keine Modularisierung der Aspekte » Funktionsweise » Szenario » Observer Pattern - Verteilung des Aspekts über den gesamten Quellcode » Generierter Code » Toolsupport » Weitere Ansätze - Quellcode ist sehr schwer zu lesen » Zusammenfassung Î Eleganter: C++ - Templates Folie 16 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 16 4.2 Templates » AOP Grundlagen » Motivation Möglichkeit generischen Code zu erzeugen Auswertung zur Übersetzungszeit » Das Szenario » AOP mit reinem C++ » Präprozessor Parametertyp wird durch konkreten Typ ersetzt » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ Typische Anwendung: generische Datentypen und Funktionen » Überblick » Funktionsweise » Szenario // Ein Stack für eine beliebige Klasse T » Observer Pattern template<class T> class Stack » Generierter Code { » Toolsupport public: Stack() : maxStack(256) // Konstruktor mit Initialisierung der Konstanten maxStack » Weitere Ansätze { s = new T[maxStack]; index=0;} » Zusammenfassung ~Stack() {delete[] s;} bool pop(T *); // abholen bool push(T *); // drauflegen private: const int maxStack; // Konstante für die Stackgröße T *s; // Der Stack selbst int index; // aktuelle Position im Stack-Array }; Beispiel: http://www.willemer.de/informatik/cpp/cpptempl.htm Folie 17 Sören Frey | Florian Walker HS Mannheim SS2006 • Generische Programmierung ist ein Paradigma, bei dem einzelne Funktionen oder Klassen möglichst allgemein beschrieben werden, so dass sie für verschiedene Datentypen anwendbar sind. • Wie beim Präprozessor erfolgt die Auswertung zur Übersetzungszeit. • Templates auch für Funktionen möglich. Beispiel: template <class T> T Algorithmus1 (T a, T b, T c){ T d = a+b+c; return d; } • Aufruf: int A = 5, B = -26, C = -48, D = 0; D = Algorithmus1<int>(A, B, C); • Wenn die Datentypen der Argumente gleichartig sind, kann die Angabe des speziellen Datentyps weggelassen werden. Der Compiler findet selbst den Typ heraus: int A = 5, B = -26, C = -48, D = 0; D = Algorithmus1 (A, B, C); Florian Walker | Sören Frey – HS Mannheim SS2006 17 4.2 Templates » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor Templates erlauben die Kapselung des Aspektcodes unabhängig vom fachlichen Code » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ class WordOOP { ... void writeTextToFile(string& text, string& file){ » Überblick Fachlicher Code des Szenarios ofstream out; » Funktionsweise out.open(file.c_str()); » Szenario out << text; » Observer Pattern out.close(); » Generierter Code } » Toolsupport string getTextFromFile(string& file){ » Weitere Ansätze char text[256]; » Zusammenfassung ifstream in; in.open(file.c_str()); if(in.is_open()){ in.getline(text, 256); in.close(); return string(text); } else return string("##ERROR WHILE OPENING FILE##"); } ... }; Folie 18 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 18 4.2 Templates – Erster Aspekt » AOP Grundlagen » Motivation » Das Szenario Sicherheitsaspekt als Wrapper-Template welches von der Fachklasse erbt » AOP mit reinem C++ » Präprozessor » Templates //generischer Wrapper welcher die Fachklasse T (WordOOP) um den SecurityAspect erweitert » Namensräume template <class T> » Begrenzungen class SecurityAspect : public T { » Schlussfolgerungen public: » AOP mit AspectC++ void writeTextToFile(string& text, string& file){ » Überblick T::writeTextToFile(encryptText(text),file); » Funktionsweise } » Szenario Before Advice string getTextFromFile(string& file){ » Observer Pattern return decryptText(T::getTextFromFile(file)); » Generierter Code } » Toolsupport » Weitere Ansätze private: » Zusammenfassung string encryptText(string& textToEncrypt){ ... return encryptedText; } string decryptText(string& textToDecrypt){ ... return decryptedText; } }; Folie 19 Sören Frey | Florian Walker HS Mannheim SS2006 • (eng.) Wrapper = Hülle • Wrapper-Template erbt von der fachlichen Klasse und überschreibt die für den Aspekt relevanten Methoden. • Before Advice: Aspekt-Code wird vor fachlichem Code ausgeführt • After Advice: Aspekt-Code wird nach fachlichem Code ausgeführt Florian Walker | Sören Frey – HS Mannheim SS2006 19 4.2 Templates – Erster Aspekt » AOP Grundlagen » Motivation » Das Szenario Sicherheitsaspekt als Wrapper-Template welches von der Fachklasse erbt » AOP mit reinem C++ » Präprozessor » Templates //generischer Wrapper welcher die Fachklasse T (WordOOP) um den SecurityAspect erweitert » Namensräume template <class T> » Begrenzungen class SecurityAspect : public T { » Schlussfolgerungen public: » AOP mit AspectC++ void writeTextToFile(string& text, string& file){ » Überblick T::writeTextToFile(encryptText(text),file); » Funktionsweise } » Szenario After Advice string getTextFromFile(string& file){ » Observer Pattern return decryptText(T::getTextFromFile(file)); » Generierter Code } » Toolsupport » Weitere Ansätze private: » Zusammenfassung string encryptText(string& textToEncrypt){ ... return encryptedText; } string decryptText(string& textToDecrypt){ ... return decryptedText; } }; Folie 20 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 20 4.2 Templates - Weaving » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ Vereinigung (weaving) von fachlichem Code und Aspektcode durch Definition eines Typ-Alias (typedef) » Präprozessor » Templates » Namensräume » Begrenzungen #include "WordOOP.h" //class WordOOP{...} » Schlussfolgerungen #include "SecurityAspect.h" //template <class T> class SecurityAspect : public T { ... } » AOP mit AspectC++ » Überblick typedef SecurityAspect<WordOOP> SecureAspectWord; » Funktionsweise » Szenario » Observer Pattern int main(){ SecureAspectWord aspectWord = SecureAspectWord(); » Generierter Code string user; » Toolsupport string passw; » Weitere Ansätze » Zusammenfassung cout << "Username: "; cin >> user; cout << "Password: "; cin >> passw; if(!aspectWord.authenticate(user, passw)) ... aspectWord.logout(); } Folie 21 Sören Frey | Florian Walker HS Mannheim SS2006 • Mithilfe der typedef-Anweisung können Synonyme (andere Namen) für bestehende Datentypen gebildet werden • Syntax: typedef Datentyp Synonym; • Beispiele: typedef unsigned short WORD; typedef unsigned long DWORD; Florian Walker | Sören Frey – HS Mannheim SS2006 21 4.2 Templates – Zwischenstand » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ Implementierung von Aspekten als Wrapper-Templates Aspekt erbt von der Fachklasse und überschreibt die notwendigen Methoden » Präprozessor » Templates » Namensräume Weaving erfolgt durch Definition von Typ-Alias » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise Generischer Aspektcode Aspekt kann auf jede Fachklasse angewendet werden, welche die gleiche Schnittstelle besitzt » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Trennung des Aspektcodes Der gesamte für den SecurityAspect relevante Code ist im Template gekapselt Fachklasse und Aspekt könnten separat weiterentwickelt werden Folie 22 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 22 4.2 Templates – Zweiter Aspekt » AOP Grundlagen Umsetzung wie erster Aspekt Î Wrapper-Template » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor template <class T>//WorkTimeAspect als Wrapper class WorktimeAspect : public T { private: » Templates time_t startTime; » Namensräume time_t endTime; » Begrenzungen public: » Schlussfolgerungen bool authenticate(string& user_, string& passw_){ » AOP mit AspectC++ startTime = time(0); » Überblick return T::authenticate(user_,passw_); //afer advice » Funktionsweise » Szenario } » Observer Pattern ^ void logout(){ » Generierter Code endTime = time(0); » Toolsupport cout << "You have been working for " << getWorkTime() << " "; » Weitere Ansätze T::logout(); //after advice » Zusammenfassung } string getWorkTime(){ Einführen einer neuen Methode (Introduction) … return workTime; } }; Folie 23 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 23 4.2 Templates - Weaving » AOP Grundlagen » Motivation Bereits bekannte Verwendung von typdef » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates #include "WordOOP.h" //class WordOOP{...} » Namensräume #include "SecurityAspect.h" //template <class T> class SecurityAspect : public T { ... } » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario #include "WorktimeAspect.h" //template <class T> class WorktimeAspect : public T { ... } typedef WorktimeAspect<SecurityAspect<WordOOP> > WorkTimeRecordingSecureAspectWord; int main(){ WorkTimeRecordingSecureAspectWord aspectWord = WorkTimeRecordingSecureAspectWord(); » Observer Pattern » Generierter Code » Toolsupport string user; » Weitere Ansätze string passw; » Zusammenfassung cout << "Username: "; cin >> user; cout << "Password: "; cin >> passw; if(!aspectWord.authenticate(user, passw)) ... aspectWord.logout(); } Folie 24 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 24 4.2 Templates - Reihenfolge » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ Reihenfolge der Aspekte: Î äußerer Aspekt zuerst » Präprozessor » Templates » Namensräume //Zuerst Arbeitszeiterfassung dann Security » Begrenzungen typedef WorktimeAspect<SecurityAspect<WordOOP> > WorkTimeRecordingSecureAspectWord; » Schlussfolgerungen //Zuerst Security dann Arbeitszeiterfassung » AOP mit AspectC++ typedef SecurityAspect<WorktimeAspect<WordOOP> > SecureWorkTimeRecordingAspectWord; » Überblick » Funktionsweise » Szenario » Observer Pattern Welches Aspekt soll zuerst ausgeführt werden? Im Beispiel noch kein Problem » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 25 Forderung: Aspekte sollten unabhängig von der Reihenfolge sein Sören Frey | Florian Walker HS Mannheim SS2006 • Reihenfolge der Aspekte im Beispiel bisher nicht relevant, da die Aspekte die Fachklasse nicht an der gleichen Stelle erweitern/modifizieren. Florian Walker | Sören Frey – HS Mannheim SS2006 25 4.2 Templates – Dritter Aspekt » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates Vorgehen wie bei den zwei vorangegangenen Aspekten template <class T> class LoggingAspect : public T { void writeMessageToFile(string& message){ » Namensräume void writeTextToFile(string& text, string& file) » Begrenzungen { » Überblick » Funktionsweise » Observer Pattern » Weitere Ansätze » Zusammenfassung writeMessageToFile(beforeUsageMessage); string getBeforeUsageMessage(){ return ""; T::writeTextToFile(text,file); } string afterUsageMessage = getAfterUsageMessage(); » Szenario » Toolsupport //Make message persistent } string beforeUsageMessage = getBeforeUsageMessage(); » Schlussfolgerungen » AOP mit AspectC++ » Generierter Code private: public: string getAfterUsageMessage(){ writeMessageToFile(afterUsageMessage); return "File accessed"; } } }; string getTextFromFile(string& file) { string beforeUsageMessage = getBeforeUsageMessage(); writeMessageToFile(beforeUsageMessage); string res = T::getTextFromFile(file); string afterUsageMessage = getAfterUsageMessage(); writeMessageToFile(afterUsageMessage); return res; } Folie 26 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 26 4.2 Templates – Dritter Aspekt » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates Aspekt verwendet „around advice“ welcher fachlichen Code innerhalb des Aspektcodes ausführt template <class T> class LoggingAspect : public T { void writeMessageToFile(string& message){ » Namensräume void writeTextToFile(string& text, string& file) » Begrenzungen { » Überblick » Funktionsweise » Observer Pattern » Weitere Ansätze » Zusammenfassung writeMessageToFile(beforeUsageMessage); string getBeforeUsageMessage(){ return ""; T::writeTextToFile(text,file); } string afterUsageMessage = getAfterUsageMessage(); » Szenario » Toolsupport //Make message persistent } string beforeUsageMessage = getBeforeUsageMessage(); » Schlussfolgerungen » AOP mit AspectC++ » Generierter Code private: public: string getAfterUsageMessage(){ writeMessageToFile(afterUsageMessage); return "File accessed"; } } }; string getTextFromFile(string& file) { string beforeUsageMessage = getBeforeUsageMessage(); writeMessageToFile(beforeUsageMessage); string res = T::getTextFromFile(file); string afterUsageMessage = getAfterUsageMessage(); writeMessageToFile(afterUsageMessage); return res; } Folie 27 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 27 4.2 Templates – Dritter Aspekt » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates Mehrfacher Code durch Definition des gleichen Advices für mehrere Joinpoints template <class T> class LoggingAspect : public T { void writeMessageToFile(string& message){ » Namensräume void writeTextToFile(string& text, string& file) » Begrenzungen { » Überblick » Funktionsweise » Observer Pattern » Weitere Ansätze » Zusammenfassung writeMessageToFile(beforeUsageMessage); string getBeforeUsageMessage(){ return ""; T::writeTextToFile(text,file); } string afterUsageMessage = getAfterUsageMessage(); » Szenario » Toolsupport //Make message persistent } string beforeUsageMessage = getBeforeUsageMessage(); » Schlussfolgerungen » AOP mit AspectC++ » Generierter Code private: public: string getAfterUsageMessage(){ writeMessageToFile(afterUsageMessage); return "File accessed"; } } }; string getTextFromFile(string& file) { string beforeUsageMessage = getBeforeUsageMessage(); writeMessageToFile(beforeUsageMessage); string res = T::getTextFromFile(file); string afterUsageMessage = getAfterUsageMessage(); writeMessageToFile(afterUsageMessage); return res; } Folie 28 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 28 4.2 Templates – Wiederverwendung » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ Anwendung eines Advice auf mehrere Joinpoints erfordert einheitliche Schnittstelle der Joinpoints » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen template <class T> class LoggingAspect : public T { public: » AOP mit AspectC++ struct WriteAction » Überblick { » Funktionsweise string message; » Szenario » Observer Pattern string file; » Generierter Code T t; void proceed(){t.writeTextToFile(message,file);} » Toolsupport » Weitere Ansätze }; » Zusammenfassung struct ReadAction { string file; string res; T t; void proceed(){res = t.getTextFromFile(file);} }; ... Folie 29 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 29 4.2 Templates – Wiederverwendung » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor Advice als Template-Funktion Action-Klasse parametrisiert die Funktion » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport template <class T> class LoggingAspect : public T { public: ... template<class action> void myAdvice(action* a) { string beforeUsageMessage = getBeforeUsageMessage(); » Weitere Ansätze writeMessageToFile(beforeUsageMessage); » Zusammenfassung a->proceed(); string afterUsageMessage = getAfterUsageMessage(); writeMessageToFile(afterUsageMessage); } ... Folie 30 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 30 4.2 Templates – Wiederverwendung » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates Advice an Joinpoints binden Durch die Action-Klassen konnte der Advice-Code in einer Funktion gekapselt werden » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ template <class T> class LoggingAspect : public T { public: » Überblick » Funktionsweise ... » Szenario void writeTextToFile(string& text, string& file) » Observer Pattern { » Generierter Code WriteAction tjp = {text,file}; » Toolsupport myAdvice(&tjp); » Weitere Ansätze } » Zusammenfassung string getTextFromFile(string& file) { ReadAction tjp = {file}; myAdvice(&tjp); return tjp.res; } ... Folie 31 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 31 4.2 Templates – Zwischenstand » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates Vermeidung von doppelten Codes durch » Namensräume » Begrenzungen » Schlussfolgerungen Delegierung an Action-Klassen » AOP mit AspectC++ » Überblick » Funktionsweise Implementierung des Advices als Template-Funktion » Szenario » Observer Pattern » Generierter Code Parametrisieren der Template-Funktionen mit den Action-Klassen » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 32 Overhead durch Speicherung zusätzlicher Argumente / Rückgabewerte Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 32 4.2 Templates » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates » Namensräume Kombination der Fachklasse mit allen Aspekten » Begrenzungen » Schlussfolgerungen typedef LoggingAspect<WorktimeAspect<SecurityAspect<WordOOP> > > LoggingAndWorkTimeRecordingSecureAspectWord; » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario Vielleicht etwas besser zu lesen: » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 33 typedef SecurityAspect<WordOOP> SecureAspectWord; typedef WorktimeAspect<SecureAspectWord> WorkTimeRecordingSecureAspectWord; typedef LoggingAspect<WorkTimeRecordingSecureAspectWord> LoggingAndWorkTimeRecordingSecureAspectWord; Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 33 4.2 Templates - Probleme » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ Eine Kerneigenschaft von AOP: Fachlicher Code ist sich nicht der Modifikation durch den Aspekt bewusst » Präprozessor » Templates » Namensräume » Begrenzungen Erweiterte Klasse kann nicht den gleichen Namen tragen wie Fachklasse » Schlussfolgerungen » AOP mit AspectC++ Auswahl erfolgt durch das gewählte Namensschema » Überblick (z.B. LoggingAndWorkTimeRecordingSecureAspectWord) » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport Î Verletzung der Eigenschaft Î verbergen der Aspekte im Client-Code » Weitere Ansätze » Zusammenfassung Folie 34 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 34 4.3 Namensräume » AOP Grundlagen » Motivation » Das Szenario Durch Verwendung von C++ namespaces Einführung von drei Namensräumen » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen components – enthält Fachklasse (WordOOP) » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern aspects – enthält die Aspekte aspectconfiguration – Auswahl der gewünschten Aspekte » Generierter Code » Toolsupport » Weitere Ansätze + Namensschema zur Auswahl entfällt » Zusammenfassung Folie 35 Sören Frey | Florian Walker HS Mannheim SS2006 • Namespaces (= namensräume) kennzeichnen Einheiten die zusammengehören. Sie verhindern Namenskonflikte und teilen den Code in logische Einheiten auf. • Importieren aller Namen eines Namensraums mittels using Direktive (using namespace myNS) • Zugriff auf Element in anderem Namensraum mittels Bereich-AuflösungsOperator (myNS::ElementA) Florian Walker | Sören Frey – HS Mannheim SS2006 35 4.3 Namensräume - Aspekte verbergen » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ namespace components { class WordOOP { ... } } namespace aspects { » Präprozessor template <class T> class LoggingAspect : public T { ... } » Templates template <class T> class SecurityAspect : public T { ... } » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise template <class T> class WorktimeAspect : public T { ... } } // AspectConfiguration.h namespace aspectconfiguration { //select a aspect » Szenario typedef aspects::SecurityAspect<components::WordOOP> WordOOP; » Observer Pattern » Generierter Code // ... » Toolsupport » Weitere Ansätze typedef aspects::WorktimeAspect<aspects::SecurityAspect<components::WordOOP>> WordOOP; } » Zusammenfassung //App.cpp #include "AspectConfiguration.h" using namespace aspectconfiguration; int main() { WordOOP wordOOP = WordOOP(); ... Folie 36 Sören Frey | Florian Walker HS Mannheim SS2006 • Vermeidung von Namenskonflikten • Fachlicher Code muss nur die Verwendung des aspectconfigurationNamensraumes enthalten Florian Walker | Sören Frey – HS Mannheim SS2006 36 4.4 Begrenzungen » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor Einsatz der vorgestellten Methoden nur sinnvoll für einfache Aspekte Anwendung eines Aspekts auf Klassen mit unterschiedlicher Schnittstelle ist nicht möglich Kein Advice auf nicht virtuelle private Methoden möglich Starke Verwendung von Templates und Namensräumen macht den Code schwer zu verstehen und erschwert die Fehlerbeseitigung Oft: mehr Code für den Wrapper als für den Aspekt » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 37 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 37 4.5 Schlussfolgerungen » AOP Grundlagen » Motivation » Das Szenario „separation of concerns“ ist mit C++ Templates ohne zusätzliche Tools und Spracherweiterungen möglich Jedoch nur sinnvoll wenn » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen eine geringe Anzahl Aspekte umzusetzen ist » AOP mit AspectC++ » Überblick » Funktionsweise die Aspekte einfacher Natur sind » Szenario » Observer Pattern » Generierter Code » Toolsupport „AOP mit reinem C++ ist wie OOP mit C“ Î Notwenigkeit von » Weitere Ansätze » Zusammenfassung Spracherweiterungen Werkzeugunterstützung für größere Projekte sinnvoll. Folie 38 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 38 5. AOP mit AspectC++ » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 39 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 39 5.1 Überblick (1) » AOP Grundlagen » Motivation » Das Szenario http://www.aspectc.org Erleichtert AOP mit C++ Ging aus universitärem Forschungsprojekt hervor Open Source Compiler ist unter GPL verfügbar für Linux, Windows, Solaris, Mac OS X Version 1.0 ist noch nicht ganz erreicht (aktuell 1.0 pre3) Beschreibt Spracherweiterung zu C++ An AspectJ angelehnte Syntax Definition von Aspekten in „Aspect-Header“ Dateien (Endung „.ah“) » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 40 Sören Frey | Florian Walker HS Mannheim SS2006 • Ursprünge an der Universität Magdeburg und der University of California, Irvine Florian Walker | Sören Frey – HS Mannheim SS2006 40 5.1 Überblick (2) » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ Pointcuts werden durch „named pointcuts“ und „matching expressions“ beschrieben » Präprozessor Name des pointcuts » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise matching expression Beispiele: pointcut functionsToMatch() = "void reset()"; Matcht Funktionen mit dem Namen „reset“, welche keine Parameter und den Rückgabetyp „void“ besitzen » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung pointcut functionsToMatch() = "% printf(...)"; Matcht Funktionen mit dem Namen „printf“, welche beliebig viele Parameter und einen beliebigen Rückgabetyp besitzen pointcut functionsToMatch() = "...::Service::%(...) const"; Matcht beliebige const Memberfunktionen der Klasse „Service“ in einem beliebigen Scope Folie 41 Sören Frey | Florian Walker HS Mannheim SS2006 • In „matching expressions“ kann auch nach Templates und deren Ausprägungen gesucht werden • Auch die Suche nach virtuellen Methoden ist möglich Florian Walker | Sören Frey – HS Mannheim SS2006 41 5.1 Überblick (3) » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ Mittels „code pointcuts“ können Punkte im Kontrollfluss sowie in der statischen Struktur definiert werden » Präprozessor » Templates Beispiele: !derived("Queue") » Namensräume » Begrenzungen » Schlussfolgerungen Beschreibt eine Menge von Klassen, welche nicht von der Klasse „Queue“ abgeleitet sind » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario execution(functionsToMatch()) » Observer Pattern Zeitpunkt, zu dem eine Funktion des Pointcuts "functionsToMatch" aufgerufen wird » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Pointcuts können mittels „pointcut expressions“ kombiniert werden Beispiel: call("void draw()") && within("Shape") Beschreibt die Menge der Aufrufe der Funktion "draw()" aus Methoden der Klasse "Shape" Folie 42 Sören Frey | Florian Walker HS Mannheim SS2006 • Weitere Beispiele für zur Definition von „code pointcuts“ wären die Pointcut Funktionen call(), construction(), destruction(), base() Florian Walker | Sören Frey – HS Mannheim SS2006 42 5.1 Überblick (4) » AOP Grundlagen » Motivation » Das Szenario AspectC++ implementiert statischen Weber Hierzu werden Bibliotheken von PUMA („Pure Manipulator“) verwendet PUMA ist ein System zur Analyse und Manipulation von C++ Quellcode AspectC++ unterstützt die Erstellung von generischem Aspekt-Code durch » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 43 1. Vererbung von Aspekten und rein virtuellen Pointcuts 2. Umfangreiche Joinpoint API Sören Frey | Florian Walker HS Mannheim SS2006 • PUMA wurde an der Universität Magdeburg entwickelt Florian Walker | Sören Frey – HS Mannheim SS2006 43 5.2 Funktionsweise (1) » AOP Grundlagen » Motivation » Das Szenario Erzeugung des ausführbaren Codes durch „source-to-source“ Transformation » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise C++ C++Code Code der Anwendung der Anwendung » Szenario » Observer Pattern » Generierter Code Weber Weber » Toolsupport TransforTransfor Transformierter mierter C++ C++Code Code » Weitere Ansätze » Zusammenfassung Compiler Compiler Ausführbare Ausführbare Datei Datei Aspektcode Aspektcode Folie 44 Sören Frey | Florian Walker HS Mannheim SS2006 • Der Weber wird in diesem Fall durch einen Präprozessor implementiert Florian Walker | Sören Frey – HS Mannheim SS2006 44 5.2 Funktionsweise (2) » AOP Grundlagen » Motivation » Das Szenario Essentiell für AspectC++ : PUMA Lexikalische, syntaktische und semantische Analyse des Quellcodes PUMA generiert Syntaxbäume, welche auch semantische Informationen enthalten Abstrakte Darstellung von Klassen, um diese analysieren zu können PUMA verwendet in neueren Versionen wiederum selbst in AspectC++ implementierte Aspekte » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 45 Sören Frey | Florian Walker HS Mannheim SS2006 • Semantische Informationen betreffen beispielsweise die Sichtbarkeit von Variablen. Angenommen eine Klasse besitzt ein Attribut und Methoden, welche mit diesem Attribut arbeiten. Will man das Attribut umbenennen, so würde eine simple Textersetzung auch lokale Variablen mit dem selben Namen in den Methoden ersetzen. PUMA ermöglicht hierbei eine feinere Steuerung. Florian Walker | Sören Frey – HS Mannheim SS2006 45 5.2 Funktionsweise (3) » AOP Grundlagen » Motivation » Das Szenario Übersicht der Architektur » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Quelle: http://www.aspectc.org/fileadmin/publications/tools2002.ps.gz Folie 46 Sören Frey | Florian Walker HS Mannheim SS2006 • In der Planungsphase werden die „pointcut expressions“ ausgewertet und die Joinpoint Mengen berechnet. Es wird ein Plan für den Weber erstellt, welcher die Joinpoints und die dazu auszuführenden Operationen enthält. Der Weber überführt den Plan in konkrete Manipulationskommandos, welche auf dem C++ Syntaxbaum von PUMA basieren. Die eigentliche Manipulation wird von der „manipulation engine“ (manipulator) von PUMA ausgeführt. Hieraus resultiert reiner C++ Code, welcher die eingewobenen Aspekte enthält. Florian Walker | Sören Frey – HS Mannheim SS2006 46 5.3 Szenario in AspectC++ (1) » AOP Grundlagen » Motivation #include <string> » Das Szenario using namespace std; for(unsigned int i = 0; i < textToEncrypt.size(); i++){ encryptedText += (((char) *iterator) + 3); » AOP mit reinem C++ » Präprozessor aspect SecurityAspect { » Templates advice execution( "% AspectWord::writeTextToFile(...)" ) : before () { » Namensräume string textToEncrypt = * (tjp->arg<0>()); » Begrenzungen return encryptedText; } * (tjp->arg<0>()) = » Schlussfolgerungen encryptText(textToEncrypt); » AOP mit AspectC++ » Überblick iterator++; } } //Simple caesar-decryption string decryptText(string& textToDecrypt){ » Funktionsweise » Szenario » Observer Pattern string decryptedText; advice execution( "% AspectWord::getTextFromFile(...)" ) : after () { string::iterator iterator = textToDecrypt.begin(); string textToDecrypt = * (tjp->result()); » Generierter Code » Toolsupport for(unsigned int i = 0; i < if(textToDecrypt != "##ERROR WHILE OPENING » Weitere Ansätze textToDecrypt.size(); i++){ FILE##") » Zusammenfassung decryptedText += (((char) *iterator) - 3); * (tjp->result()) = decryptText(textToDecrypt); iterator++; } } return decryptedText; //Simple caesar-encryption } string encryptText(string& textToEncrypt){ string encryptedText; }; string::iterator iterator = textToEncrypt.begin(); Folie 47 Sören Frey | Florian Walker HS Mannheim SS2006 • Nachfolgend wird der Aspekt zur Definition der Sicherheitsfunktionalitäten beschrieben Florian Walker | Sören Frey – HS Mannheim SS2006 47 5.3 Szenario in AspectC++ (2) » AOP Grundlagen » Motivation #include <string> » Das Szenario using namespace std; Definition eines neuen Aspektes for(unsigned int i = 0; i < textToEncrypt.size(); i++){ encryptedText += (((char) *iterator) + 3); » AOP mit reinem C++ » Präprozessor aspect SecurityAspect { » Templates advice execution( "% AspectWord::writeTextToFile(...)" ) : before () { » Namensräume string textToEncrypt = * (tjp->arg<0>()); » Begrenzungen return encryptedText; } * (tjp->arg<0>()) = » Schlussfolgerungen encryptText(textToEncrypt); » AOP mit AspectC++ » Überblick iterator++; } } //Simple caesar-decryption string decryptText(string& textToDecrypt){ » Funktionsweise » Szenario » Observer Pattern string decryptedText; advice execution( "% AspectWord::getTextFromFile(...)" ) : after () { string::iterator iterator = textToDecrypt.begin(); string textToDecrypt = * (tjp->result()); » Generierter Code » Toolsupport for(unsigned int i = 0; i < if(textToDecrypt != "##ERROR WHILE OPENING » Weitere Ansätze textToDecrypt.size(); i++){ FILE##") » Zusammenfassung decryptedText += (((char) *iterator) - 3); * (tjp->result()) = decryptText(textToDecrypt); iterator++; } } return decryptedText; //Simple caesar-encryption } string encryptText(string& textToEncrypt){ string encryptedText; }; string::iterator iterator = textToEncrypt.begin(); Folie 48 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 48 5.3 Szenario in AspectC++ (3) » AOP Grundlagen » Motivation #include <string> » Das Szenario using namespace std; for(unsigned int i = 0; i < textToEncrypt.size(); i++){ Advice, welches die Daten vor dem encryptedText += verschlüsselt. (((char) *iterator) + 3); persistenten Schreiben Zugriff auf Daten des betreffenden iterator++; Joinpoints über Variable „tjp“. } Manipulation des Arguments, mit welchem return encryptedText; „writeTextToFile()“ aufgerufen wird » AOP mit reinem C++ » Präprozessor aspect SecurityAspect { » Templates advice execution( "% AspectWord::writeTextToFile(...)" ) : before () { » Namensräume » Begrenzungen string textToEncrypt = * (tjp->arg<0>()); » Schlussfolgerungen * (tjp->arg<0>()) = encryptText(textToEncrypt); » AOP mit AspectC++ » Überblick } } //Simple caesar-decryption string decryptText(string& textToDecrypt){ » Funktionsweise » Szenario » Observer Pattern string decryptedText; advice execution( "% AspectWord::getTextFromFile(...)" ) : after () { string::iterator iterator = textToDecrypt.begin(); string textToDecrypt = * (tjp->result()); » Generierter Code » Toolsupport for(unsigned int i = 0; i < if(textToDecrypt != "##ERROR WHILE OPENING » Weitere Ansätze textToDecrypt.size(); i++){ FILE##") » Zusammenfassung decryptedText += (((char) *iterator) - 3); * (tjp->result()) = decryptText(textToDecrypt); iterator++; } } return decryptedText; //Simple caesar-encryption } string encryptText(string& textToEncrypt){ string encryptedText; }; string::iterator iterator = textToEncrypt.begin(); Folie 49 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 49 5.3 Szenario in AspectC++ (4) » AOP Grundlagen » Motivation #include <string> » Das Szenario using namespace std; for(unsigned int i = 0; i < textToEncrypt.size(); i++){ encryptedText += (((char) *iterator) + 3); » AOP mit reinem C++ » Präprozessor aspect SecurityAspect { » Templates advice execution( "% AspectWord::writeTextToFile(...)" ) : before () { » Namensräume string textToEncrypt = * (tjp->arg<0>()); » Begrenzungen return encryptedText; } * (tjp->arg<0>()) = » Schlussfolgerungen encryptText(textToEncrypt); » AOP mit AspectC++ » Überblick iterator++; } } Advice, welches die Daten nach dem Lesen von der Festplatte entschlüsselt. //Simple caesar-decryption string decryptText(string& Der Rückgabewert der FunktiontextToDecrypt){ „getTextFromFile()“ wird geändert, so string decryptedText; dass der entschlüsselte Wert zurück string::iterator iterator = gegeben wird » Funktionsweise » Szenario » Observer Pattern advice execution( "% AspectWord::getTextFromFile(...)" ) : after () { textToDecrypt.begin(); string textToDecrypt = * (tjp->result()); » Generierter Code » Toolsupport for(unsigned int i = 0; i < if(textToDecrypt != "##ERROR WHILE OPENING » Weitere Ansätze textToDecrypt.size(); i++){ FILE##") » Zusammenfassung decryptedText += (((char) *iterator) - 3); * (tjp->result()) = decryptText(textToDecrypt); iterator++; } } return decryptedText; //Simple caesar-encryption } string encryptText(string& textToEncrypt){ string encryptedText; }; string::iterator iterator = textToEncrypt.begin(); Folie 50 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 50 5.3 Szenario in AspectC++ (5) » AOP Grundlagen » Motivation #include <string> » Das Szenario using namespace std; for(unsigned int i = 0; i < textToEncrypt.size(); i++){ encryptedText += (((char) *iterator) + 3); » AOP mit reinem C++ » Präprozessor aspect SecurityAspect { » Templates advice execution( "% AspectWord::writeTextToFile(...)" ) : before () { » Namensräume string textToEncrypt = * Ver(tjp->arg<0>()); Einfache Funktionen zum und » Begrenzungen Entschlüsseln der Daten mittels Cäsar* (tjp->arg<0>()) = Code » Schlussfolgerungen encryptText(textToEncrypt); » AOP mit AspectC++ » Überblick } iterator++; } return encryptedText; } //Simple caesar-decryption string decryptText(string& textToDecrypt){ » Funktionsweise » Szenario » Observer Pattern string decryptedText; advice execution( "% AspectWord::getTextFromFile(...)" ) : after () { string::iterator iterator = textToDecrypt.begin(); string textToDecrypt = * (tjp->result()); » Generierter Code » Toolsupport for(unsigned int i = 0; i < if(textToDecrypt != "##ERROR WHILE OPENING » Weitere Ansätze textToDecrypt.size(); i++){ FILE##") » Zusammenfassung decryptedText += (((char) *iterator) - 3); * (tjp->result()) = decryptText(textToDecrypt); iterator++; } } return decryptedText; //Simple caesar-encryption } string encryptText(string& textToEncrypt){ string encryptedText; }; string::iterator iterator = textToEncrypt.begin(); Folie 51 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 51 5.3 Szenario in AspectC++ (6) » AOP Grundlagen » Motivation » Das Szenario #include "time.h" #include "time.h" » AOP mit reinem C++ #include <string> #include <iostream> » Präprozessor #include <sstream> using namespace std; » Templates » Namensräume using namespace std; » Begrenzungen » Schlussfolgerungen aspect WorktimeAspect2{ aspect WorktimeAspect1{ » AOP mit AspectC++ advice execution("% advice "AspectWord" : slice struct{ » Überblick time_t startTime; » Funktionsweise time_t endTime; AspectWord::authenticate(...)") && that(aspectWord) : after(AspectWord& aspectWord){ aspectWord.startTime = time(0); » Szenario } » Observer Pattern string getWorkTime(){ » Generierter Code » Toolsupport » Weitere Ansätze // Implementierung hier advice execution("% AspectWord::logout(...)") // uninteressant && that(aspectWord) : before(AspectWord& } » Zusammenfassung aspectWord) }; { }; aspectWord.endTime = time(0); cout << "You have been working for " << aspectWord.getWorkTime() << " "; } }; Folie 52 Sören Frey | Florian Walker HS Mannheim SS2006 • Nachfolgend werden die Aspekte zur Erfassung der Arbeitszeit beschrieben Florian Walker | Sören Frey – HS Mannheim SS2006 52 5.3 Szenario in AspectC++ (7) » AOP Grundlagen » Motivation » Das Szenario #include "time.h" » AOP mit reinem C++ #include <string> » Präprozessor #include <sstream> Bug in AspectC++ erzwingt Aufteilung in 2 Aspekte für Worktime-Komponente using namespace std; » Begrenzungen » Schlussfolgerungen #include <iostream> using namespace std; » Templates » Namensräume #include "time.h" aspect WorktimeAspect2{ aspect WorktimeAspect1{ » AOP mit AspectC++ advice execution("% advice "AspectWord" : slice struct{ » Überblick time_t startTime; » Funktionsweise time_t endTime; AspectWord::authenticate(...)") && that(aspectWord) : after(AspectWord& aspectWord){ aspectWord.startTime = time(0); » Szenario } » Observer Pattern string getWorkTime(){ » Generierter Code » Toolsupport » Weitere Ansätze // Implementierung hier advice execution("% AspectWord::logout(...)") // uninteressant && that(aspectWord) : before(AspectWord& } » Zusammenfassung aspectWord) }; { }; aspectWord.endTime = time(0); cout << "You have been working for " << aspectWord.getWorkTime() << " "; } }; Folie 53 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 53 5.3 Szenario in AspectC++ (8) » AOP Grundlagen » Motivation » Das Szenario #include "time.h" #include "time.h" » AOP mit reinem C++ #include <string> #include <iostream> » Präprozessor #include <sstream> using namespace std; » Templates » Namensräume using namespace std; » Begrenzungen » Schlussfolgerungen aspect WorktimeAspect2{ aspect WorktimeAspect1{ » AOP mit AspectC++ advice "AspectWord" : slice struct{ » Überblick time_t startTime; » Funktionsweise time_t endTime; Introduction von 2 Variablen und einer advice execution("% Methode in Applikation. Definition der AspectWord::authenticate(...)") && Variablen im Aspekt wäre semantisch nicht gleichwertig ! that(aspectWord) : after(AspectWord& aspectWord){ aspectWord.startTime = time(0); » Szenario } » Observer Pattern string getWorkTime(){ » Generierter Code » Toolsupport » Weitere Ansätze // Implementierung hier advice execution("% AspectWord::logout(...)") // uninteressant && that(aspectWord) : before(AspectWord& } » Zusammenfassung aspectWord) }; { }; aspectWord.endTime = time(0); cout << "You have been working for " << aspectWord.getWorkTime() << " "; } }; Folie 54 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 54 5.3 Szenario in AspectC++ (9) » AOP Grundlagen » Motivation » Das Szenario #include "time.h" #include "time.h" » AOP mit reinem C++ #include <string> #include <iostream> » Präprozessor #include <sstream> using namespace std; » Templates » Namensräume » Begrenzungen » Schlussfolgerungen using namespace std; Advice zum Starten der Zeitmessung. Eine Kontextvariable „aspectWord“ wird an „that()“ aspect WorktimeAspect1{ aspect WorktimeAspect2{ advice execution("% (die aufrufende Instanz) gebunden. Hierüber advice struct{ kann"AspectWord" im Advice auf : dieslice neu eingeführte time_t startTime; Variable zugegriffen werden » AOP mit AspectC++ » Überblick » Funktionsweise AspectWord::authenticate(...)") && that(aspectWord) : after(AspectWord& aspectWord){ time_t endTime; aspectWord.startTime = time(0); » Szenario } » Observer Pattern string getWorkTime(){ » Generierter Code » Toolsupport » Weitere Ansätze // Implementierung hier advice execution("% AspectWord::logout(...)") // uninteressant && that(aspectWord) : before(AspectWord& } » Zusammenfassung aspectWord) }; { }; aspectWord.endTime = time(0); cout << "You have been working for " << aspectWord.getWorkTime() << " "; } }; Folie 55 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 55 5.3 Szenario in AspectC++ (10) » AOP Grundlagen » Motivation » Das Szenario #include "time.h" #include "time.h" » AOP mit reinem C++ #include <string> #include <iostream> » Präprozessor #include <sstream> using namespace std; » Templates » Namensräume using namespace std; » Begrenzungen » Schlussfolgerungen aspect WorktimeAspect2{ aspect WorktimeAspect1{ » AOP mit AspectC++ advice execution("% advice "AspectWord" : slice struct{ » Überblick time_t startTime; » Funktionsweise time_t endTime; AspectWord::authenticate(...)") && that(aspectWord) : after(AspectWord& aspectWord){ aspectWord.startTime = time(0); » Szenario } » Observer Pattern string getWorkTime(){ » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung }; Advice zum Beenden der Zeitmessung und // Implementierung hier Ausgabe der geleisteten Arbeitszeit. Wiederum // uninteressant wird über eine Kontextvariable auf die per Introduction neu eingeführten Klassenmember } zugegriffen advice execution("% AspectWord::logout(...)") && that(aspectWord) : before(AspectWord& aspectWord) { }; aspectWord.endTime = time(0); cout << "You have been working for " << aspectWord.getWorkTime() << " "; } }; Folie 56 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 56 5.3 Szenario in AspectC++ (11) » AOP Grundlagen » Motivation #include <string> » Das Szenario using namespace std; aspect WritingLoggingAspect : public GenericLoggingAspect{ string getBeforeUsageMessage() { » AOP mit reinem C++ » Präprozessor aspect GenericLoggingAspect { return ""; » Templates virtual string getBeforeUsageMessage() = 0; } » Namensräume virtual string getAfterUsageMessage() = 0; string getAfterUsageMessage() { pointcut virtual functions() = 0; } advice execution(functions()) : around() { pointcut functions() = "% » Begrenzungen return "File written"; » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise string beforeUsageMessage = » Szenario getBeforeUsageMessage(); » Observer Pattern AspectWord::writeTextToFile(...)"; }; writeMessageToFile(beforeUsageMessage); » Generierter Code tjp->proceed(); » Toolsupport » Weitere Ansätze » Zusammenfassung aspect ReadingLoggingAspect : public string afterUsageMessage = GenericLoggingAspect{ getAfterUsageMessage(); string getBeforeUsageMessage() { writeMessageToFile(afterUsageMessage); return ""; } } string getAfterUsageMessage() { void writeMessageToFile(string& message){ return "File read"; //Make message persistent } } }; pointcut functions() = "% AspectWord::getTextFromFile(...)"; }; Folie 57 Sören Frey | Florian Walker HS Mannheim SS2006 • Nachfolgend wird der generische Aspekt zum Loggen von Daten und dessen reale Ausgestaltungen beschrieben Florian Walker | Sören Frey – HS Mannheim SS2006 57 5.3 Szenario in AspectC++ (12) » AOP Grundlagen » Motivation » Das Szenario #include <string> aspect WritingLoggingAspect : public using namespace std; GenericLoggingAspect{ » AOP mit reinem C++ » Präprozessor » Templates string getBeforeUsageMessage() { aspect GenericLoggingAspect { » Namensräume » Begrenzungen return ""; virtual string getBeforeUsageMessage() = 0; } virtual string getAfterUsageMessage() = 0; string getAfterUsageMessage() { pointcut virtual functions() = 0; } return "File written"; » Schlussfolgerungen Definition eines generischen Aspektes. Hiervon werden 2 konkrete Aspekte abgeleitet advice execution(functions()) : around() { pointcut functions() = "% » AOP mit AspectC++ » Überblick » Funktionsweise string beforeUsageMessage = » Szenario getBeforeUsageMessage(); » Observer Pattern » Generierter Code writeMessageToFile(beforeUsageMessage); » Toolsupport tjp->proceed(); AspectWord::writeTextToFile(...)"; }; aspect ReadingLoggingAspect : public » Weitere Ansätze string afterUsageMessage = GenericLoggingAspect{ » Zusammenfassung getAfterUsageMessage(); string getBeforeUsageMessage() { writeMessageToFile(afterUsageMessage); return ""; } } string getAfterUsageMessage() { void writeMessageToFile(string& message){ return "File read"; //Make message persistent } } }; pointcut functions() = "% AspectWord::getTextFromFile(...)"; }; Folie 58 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 58 5.3 Szenario in AspectC++ (13) » AOP Grundlagen » Motivation » Das Szenario #include <string> aspect WritingLoggingAspect : public using namespace std; GenericLoggingAspect{ » AOP mit reinem C++ » Präprozessor » Templates string getBeforeUsageMessage() { aspect GenericLoggingAspect { virtual string getBeforeUsageMessage() = 0; » Namensräume » Begrenzungen Der Aspekt erhält durch rein virtuelle return ""; Methoden und einen rein virtuellen } Pointcut eine generische Ausgestaltung virtual string getAfterUsageMessage() = 0; string getAfterUsageMessage() { pointcut virtual functions() = 0; } advice execution(functions()) : around() { pointcut functions() = "% return "File written"; » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise string beforeUsageMessage = » Szenario getBeforeUsageMessage(); » Observer Pattern » Generierter Code writeMessageToFile(beforeUsageMessage); » Toolsupport tjp->proceed(); AspectWord::writeTextToFile(...)"; }; aspect ReadingLoggingAspect : public » Weitere Ansätze string afterUsageMessage = GenericLoggingAspect{ » Zusammenfassung getAfterUsageMessage(); string getBeforeUsageMessage() { writeMessageToFile(afterUsageMessage); return ""; } } string getAfterUsageMessage() { void writeMessageToFile(string& message){ return "File read"; //Make message persistent } } }; pointcut functions() = "% AspectWord::getTextFromFile(...)"; }; Folie 59 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 59 5.3 Szenario in AspectC++ (14) » AOP Grundlagen » Motivation » Das Szenario #include <string> aspect WritingLoggingAspect : public using namespace std; GenericLoggingAspect{ » AOP mit reinem C++ » Präprozessor » Templates string getBeforeUsageMessage() { aspect GenericLoggingAspect { » Namensräume » Begrenzungen return ""; virtual string getBeforeUsageMessage() = 0; } virtual string getAfterUsageMessage() = 0; string getAfterUsageMessage() { pointcut virtual functions() = 0; } return "File written"; » Schlussfolgerungen » AOP mit AspectC++ » Überblick advice execution(functions()) : around() { » Funktionsweise string beforeUsageMessage = » Szenario getBeforeUsageMessage(); » Observer Pattern » Generierter Code writeMessageToFile(beforeUsageMessage); » Toolsupport tjp->proceed(); Im „around-Advice“ des generischen pointcut functions() "% Aspektes werden die jeweiligen= Meldungen (vor und nach einem Methoden-Aufruf) AspectWord::writeTextToFile(...)"; ausgegeben. Durch „tjp->proceed()“ wird }; der eigentliche Methodenrumpf ausgeführt aspect ReadingLoggingAspect : public » Weitere Ansätze string afterUsageMessage = GenericLoggingAspect{ » Zusammenfassung getAfterUsageMessage(); string getBeforeUsageMessage() { writeMessageToFile(afterUsageMessage); return ""; } } string getAfterUsageMessage() { void writeMessageToFile(string& message){ return "File read"; //Make message persistent } } }; pointcut functions() = "% AspectWord::getTextFromFile(...)"; }; Folie 60 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 60 5.3 Szenario in AspectC++ (15) » AOP Grundlagen » Motivation » Das Szenario #include <string> aspect WritingLoggingAspect : public using namespace std; GenericLoggingAspect{ » AOP mit reinem C++ » Präprozessor » Templates string getBeforeUsageMessage() { aspect GenericLoggingAspect { » Namensräume » Begrenzungen return ""; virtual string getBeforeUsageMessage() = 0; } virtual string getAfterUsageMessage() = 0; string getAfterUsageMessage() { pointcut virtual functions() = 0; } advice execution(functions()) : around() { pointcut functions() = "% return "File written"; » Schlussfolgerungen » AOP mit AspectC++ » Überblick In den konkreten Aspekten werden die rein string Methoden beforeUsageMessage = Somit wird virtuellen überschrieben. festgelegt, was bei Schreib- und Lesevorgängen getBeforeUsageMessage(); jeweils vor und nach dem Methodenaufruf writeMessageToFile(beforeUsageMessage); ausgegeben werden soll » Funktionsweise » Szenario » Observer Pattern » Generierter Code tjp->proceed(); » Toolsupport AspectWord::writeTextToFile(...)"; }; aspect ReadingLoggingAspect : public » Weitere Ansätze string afterUsageMessage = GenericLoggingAspect{ » Zusammenfassung getAfterUsageMessage(); string getBeforeUsageMessage() { writeMessageToFile(afterUsageMessage); return ""; } } string getAfterUsageMessage() { void writeMessageToFile(string& message){ return "File read"; //Make message persistent } } }; pointcut functions() = "% AspectWord::getTextFromFile(...)"; }; Folie 61 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 61 5.3 Szenario in AspectC++ (16) » AOP Grundlagen » Motivation » Das Szenario #include <string> aspect WritingLoggingAspect : public using namespace std; GenericLoggingAspect{ » AOP mit reinem C++ » Präprozessor » Templates string getBeforeUsageMessage() { aspect GenericLoggingAspect { » Namensräume » Begrenzungen return ""; virtual string getBeforeUsageMessage() = 0; } virtual string getAfterUsageMessage() = 0; string getAfterUsageMessage() { pointcut virtual functions() = 0; } advice execution(functions()) : around() { pointcut functions() = "% return "File written"; » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise string beforeUsageMessage = » Szenario getBeforeUsageMessage(); » Observer Pattern AspectWord::writeTextToFile(...)"; }; writeMessageToFile(beforeUsageMessage); » Generierter Code Durch die Realisierung des formals rein tjp->proceed(); virtuellen Pointcuts in den konkreten Aspekten wird festgelegt, bei welchen string afterUsageMessage = Methoden der Logging-Vorgang durchgeführt getAfterUsageMessage(); werden soll » Toolsupport » Weitere Ansätze » Zusammenfassung aspect ReadingLoggingAspect : public GenericLoggingAspect{ string getBeforeUsageMessage() { writeMessageToFile(afterUsageMessage); return ""; } } string getAfterUsageMessage() { void writeMessageToFile(string& message){ return "File read"; //Make message persistent } } }; pointcut functions() = "% AspectWord::getTextFromFile(...)"; }; Folie 62 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 62 5.4 Generisches Observer Pattern (1) » AOP Grundlagen » Motivation » Das Szenario Szenario: » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Quelle: http://www.aspectc.org/fileadmin/publications/aosd-2005-tut-2x2.pdf Folie 63 Sören Frey | Florian Walker HS Mannheim SS2006 • Das Beispiel zeigt, dass auch bei der Implementierung von Design Patterns durch AOP eine weitergehende Modularisierung und eine „separation of concerns“ möglich ist Florian Walker | Sören Frey – HS Mannheim SS2006 63 5.4 Generisches Observer Pattern (2) » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Quelle: http://www.aspectc.org/fileadmin/publications/aosd-2005-tut-2x2.pdf Folie 64 Sören Frey | Florian Walker HS Mannheim SS2006 • Ein Beobachter möchte über Geschehnisse in einer anderen Klasse in Kenntnis gesetzt werden, um darauf angemessen reagieren zu können. Hierzu kann er sich bei dem so genannten „Subject“ registrieren und deregistrieren. Im Beispiel soll ein Beobachter die Methode „Draw()“ aufrufen, wenn er ein Update-Ereignis erhält. Florian Walker | Sören Frey – HS Mannheim SS2006 64 5.4 Generisches Observer Pattern (3) » AOP Grundlagen » Motivation aspect ObserverPattern { » Das Szenario ... » AOP mit reinem C++ public: » Präprozessor struct ISubject {}; » Templates struct IObserver { » Namensräume virtual void update (ISubject *) = 0;}; » Begrenzungen » Schlussfolgerungen pointcut virtual observers() = 0; » AOP mit AspectC++ pointcut virtual subjects() = 0; » Überblick pointcut virtual subjectChange() = execution( » Funktionsweise "% ...::%(...)" && !"% ...::%(...) const" ) » Szenario && within( subjects() ); » Observer Pattern » Generierter Code advice observers () : baseclass( IObserver ); » Toolsupport advice subjects() : baseclass( ISubject ); » Weitere Ansätze advice subjectChange() : after () { » Zusammenfassung ISubject* subject = tjp->that(); updateObservers( subject ); } void updateObservers( ISubject* subject ) { ... } void addObserver( ISubject* subject, IObserver* observer ) { ... } void remObserver( ISubject* subject, IObserver* observer ) { ... } }; Folie 65 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 65 5.4 Generisches Observer Pattern (4) » AOP Grundlagen » Motivation aspect ObserverPattern { » Das Szenario ... » AOP mit reinem C++ public: » Präprozessor Interfaces für die Subjekt- und Observer-Rollen struct ISubject {}; » Templates struct IObserver { » Namensräume virtual void update (ISubject *) = 0;}; » Begrenzungen » Schlussfolgerungen pointcut virtual observers() = 0; » AOP mit AspectC++ pointcut virtual subjects() = 0; » Überblick pointcut virtual subjectChange() = execution( » Funktionsweise » Szenario "% ...::%(...)" && !"% ...::%(...) const" ) » Observer Pattern && within( subjects() ); » Generierter Code advice observers () : baseclass( IObserver ); » Toolsupport » Weitere Ansätze advice subjects() : baseclass( ISubject ); » Zusammenfassung advice subjectChange() : after () { ISubject* subject = tjp->that(); updateObservers( subject ); } void updateObservers( ISubject* subject ) { ... } void addObserver( ISubject* subject, IObserver* observer ) { ... } void remObserver( ISubject* subject, IObserver* observer ) { ... } }; Folie 66 Sören Frey | Florian Walker HS Mannheim SS2006 • Jeder Beobachter soll eine update-Methode erhalten Florian Walker | Sören Frey – HS Mannheim SS2006 66 5.4 Generisches Observer Pattern (5) » AOP Grundlagen » Motivation aspect ObserverPattern { » Das Szenario ... » AOP mit reinem C++ public: » Präprozessor struct ISubject {}; » Templates struct IObserver { » Namensräume virtual void update (ISubject *) = 0;}; » Begrenzungen » Schlussfolgerungen Abstrakte Pointcuts, welche Subjekte und Observer definieren (müssen überschrieben werden) pointcut virtual observers() = 0; » AOP mit AspectC++ pointcut virtual subjects() = 0; » Überblick pointcut virtual subjectChange() = execution( » Funktionsweise "% ...::%(...)" && !"% ...::%(...) const" ) » Szenario && within( subjects() ); » Observer Pattern » Generierter Code advice observers () : baseclass( IObserver ); » Toolsupport » Weitere Ansätze advice subjects() : baseclass( ISubject ); » Zusammenfassung advice subjectChange() : after () { ISubject* subject = tjp->that(); updateObservers( subject ); } void updateObservers( ISubject* subject ) { ... } void addObserver( ISubject* subject, IObserver* observer ) { ... } void remObserver( ISubject* subject, IObserver* observer ) { ... } }; Folie 67 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 67 5.4 Generisches Observer Pattern (6) » AOP Grundlagen » Motivation aspect ObserverPattern { » Das Szenario ... » AOP mit reinem C++ public: » Präprozessor struct ISubject {}; » Templates struct IObserver { » Namensräume virtual void update (ISubject *) = 0;}; » Begrenzungen » Schlussfolgerungen pointcut virtual observers() = 0; » AOP mit AspectC++ Pointcut der alle zustandsändernden Methoden definiert (standardmässig bei der Ausführung von allen nicht konstanten Methoden in Subjekten) pointcut virtual subjects() = 0; » Überblick pointcut virtual subjectChange() = execution( » Funktionsweise "% ...::%(...)" && !"% ...::%(...) const" ) » Szenario && within( subjects() ); » Observer Pattern » Generierter Code advice observers () : baseclass( IObserver ); » Toolsupport » Weitere Ansätze advice subjects() : baseclass( ISubject ); » Zusammenfassung advice subjectChange() : after () { ISubject* subject = tjp->that(); updateObservers( subject ); } void updateObservers( ISubject* subject ) { ... } void addObserver( ISubject* subject, IObserver* observer ) { ... } void remObserver( ISubject* subject, IObserver* observer ) { ... } }; Folie 68 Sören Frey | Florian Walker HS Mannheim SS2006 • Selbstverständlich könnte auch eine spezifischere Festlegung auf bestimmte Funktionen erfolgen, die „matching expressions“ sind hierbei mächtige Werkzeuge Florian Walker | Sören Frey – HS Mannheim SS2006 68 5.4 Generisches Observer Pattern (7) » AOP Grundlagen » Motivation aspect ObserverPattern { » Das Szenario ... » AOP mit reinem C++ public: » Präprozessor struct ISubject {}; » Templates struct IObserver { » Namensräume virtual void update (ISubject *) = 0;}; » Begrenzungen » Schlussfolgerungen pointcut virtual observers() = 0; » AOP mit AspectC++ pointcut virtual subjects() = 0; » Überblick pointcut virtual subjectChange() = execution( » Funktionsweise "% ...::%(...)" && !"% ...::%(...) const" ) » Szenario && within( subjects() ); » Observer Pattern Introduction der RollenInterfaces als zusätzliche Basisklassen in Subjekten und Observern » Generierter Code advice observers () : baseclass( IObserver ); » Toolsupport » Weitere Ansätze advice subjects() : baseclass( ISubject ); » Zusammenfassung advice subjectChange() : after () { ISubject* subject = tjp->that(); updateObservers( subject ); } void updateObservers( ISubject* subject ) { ... } void addObserver( ISubject* subject, IObserver* observer ) { ... } void remObserver( ISubject* subject, IObserver* observer ) { ... } }; Folie 69 Sören Frey | Florian Walker HS Mannheim SS2006 • Matcht eine Klasse mit den angegeben Subjekten oder Beobachtern, so wird ihr automatisch über Vererbung die jeweilige Rolle zugewiesen Florian Walker | Sören Frey – HS Mannheim SS2006 69 5.4 Generisches Observer Pattern (8) » AOP Grundlagen » Motivation aspect ObserverPattern { » Das Szenario ... » AOP mit reinem C++ public: » Präprozessor struct ISubject {}; » Templates struct IObserver { » Namensräume virtual void update (ISubject *) = 0;}; » Begrenzungen » Schlussfolgerungen pointcut virtual observers() = 0; » AOP mit AspectC++ pointcut virtual subjects() = 0; » Überblick pointcut virtual subjectChange() = execution( » Funktionsweise "% ...::%(...)" && !"% ...::%(...) const" ) » Szenario && within( subjects() ); » Observer Pattern » Generierter Code advice observers () : baseclass( IObserver ); » Toolsupport » Weitere Ansätze advice subjects() : baseclass( ISubject ); » Zusammenfassung advice subjectChange() : after () { Advice, der die Observer nach dem Ausführen einer zustandsändernden Methode updated ISubject* subject = tjp->that(); updateObservers( subject ); } void updateObservers( ISubject* subject ) { ... } void addObserver( ISubject* subject, IObserver* observer ) { ... } void remObserver( ISubject* subject, IObserver* observer ) { ... } }; Folie 70 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 70 5.4 Generisches Observer Pattern (9) » AOP Grundlagen » Motivation » Das Szenario aspect ClockObserver : public ObserverPattern { // define the participants » AOP mit reinem C++ » Präprozessor pointcut subjects() = "ClockTimer"; » Templates pointcut observers() = "DigitalClock"|| » Namensräume "AnalogClock"; » Begrenzungen » Schlussfolgerungen public: » AOP mit AspectC++ // define what to do in case of a notification » Überblick advice observers() : void update( » Funktionsweise ObserverPattern::ISubject* s ) { » Szenario Draw(); » Observer Pattern » Generierter Code » Toolsupport } }; » Weitere Ansätze » Zusammenfassung Folie 71 Sören Frey | Florian Walker HS Mannheim SS2006 • Zur Anwendung des Observer Patterns reicht es nun aus, lediglich die gewünschten Subjekte und Beobachter mittels Pointcuts zu spezifizieren und den update-Advice zu überschreiben Florian Walker | Sören Frey – HS Mannheim SS2006 71 5.5 Generierter Code (1) » AOP Grundlagen » Motivation » Das Szenario aspect SecurityAspect { advice execution( "% AspectWord::writeTextToFile(...)" ) : before () » AOP mit reinem C++ { » Präprozessor string textToEncrypt = * (tjp->arg<0>()); » Templates » Namensräume * (tjp->arg<0>()) = encryptText(textToEncrypt); » Begrenzungen } » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario ... }; SecurityAspect.ah » Observer Pattern » Generierter Code class SecurityAspect { » Toolsupport static SecurityAspect *aspectof () { » Weitere Ansätze static SecurityAspect __instance; » Zusammenfassung return &__instance; } template<class JoinPoint> void __a0_before(JoinPoint *tjp){ ... } ... }; AspectWord.acc Folie 72 Sören Frey | Florian Walker HS Mannheim SS2006 • Der Beispielcode stellt lediglich einen kleinen Ausschnitt aus dem unfangreichen generierten Code dar Florian Walker | Sören Frey – HS Mannheim SS2006 72 5.5 Generierter Code (2) » AOP Grundlagen » Motivation » Das Szenario aspect SecurityAspect { advice execution( "% AspectWord::writeTextToFile(...)" ) : before () » AOP mit reinem C++ { » Präprozessor string textToEncrypt = * (tjp->arg<0>()); » Templates » Namensräume * (tjp->arg<0>()) = encryptText(textToEncrypt); » Begrenzungen } » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario Aspekte werden zu Klassen transformiert ... }; SecurityAspect.ah » Observer Pattern » Generierter Code class SecurityAspect { » Toolsupport static SecurityAspect *aspectof () { » Weitere Ansätze static SecurityAspect __instance; » Zusammenfassung return &__instance; } template<class JoinPoint> void __a0_before(JoinPoint *tjp){ ... } ... }; AspectWord.acc Folie 73 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 73 5.5 Generierter Code (3) » AOP Grundlagen » Motivation » Das Szenario aspect SecurityAspect { advice execution( "% AspectWord::writeTextToFile(...)" ) : before () » AOP mit reinem C++ { » Präprozessor string textToEncrypt = * (tjp->arg<0>()); » Templates » Namensräume * (tjp->arg<0>()) = encryptText(textToEncrypt); » Begrenzungen } » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario Eine globale Instanz des Aspektes wird standardmässig erstellt ... }; SecurityAspect.ah » Observer Pattern » Generierter Code class SecurityAspect { » Toolsupport static SecurityAspect *aspectof () { » Weitere Ansätze static SecurityAspect __instance; » Zusammenfassung return &__instance; } template<class JoinPoint> void __a0_before(JoinPoint *tjp){ ... } ... }; AspectWord.acc Folie 74 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 74 5.5 Generierter Code (4) » AOP Grundlagen » Motivation » Das Szenario aspect SecurityAspect { advice execution( "% AspectWord::writeTextToFile(...)" ) : before () » AOP mit reinem C++ { » Präprozessor string textToEncrypt = * (tjp->arg<0>()); » Templates » Namensräume * (tjp->arg<0>()) = encryptText(textToEncrypt); » Begrenzungen } » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario Advices werden zu Memberfunktionen umgeformt ... }; SecurityAspect.ah » Observer Pattern » Generierter Code class SecurityAspect { » Toolsupport static SecurityAspect *aspectof () { » Weitere Ansätze static SecurityAspect __instance; » Zusammenfassung return &__instance; } template<class JoinPoint> void __a0_before(JoinPoint *tjp){ ... } ... }; AspectWord.acc Folie 75 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 75 5.6 Toolsupport (1) » AOP Grundlagen » Motivation » Das Szenario AspectC++ Compiler bedienbar über Kommandozeile Integration in Eclipse mittels ACDT (AspectC++ Development Tools) Plugin ACDT basiert auf Eclipse-Projekt CDT (C/C++ Development Tools) ACDT bietet: » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport Syntax-Highlighting » Weitere Ansätze » Zusammenfassung Erweiterte Outline-View, welche Aspekte, Advices und Pointcuts zeigt Managed Builder, welcher Make-Files automatisch erstellt Grafische Darstellung von Joinpoints und Navigation zu entsprechenden Funktionen, Klassen etc. Folie 76 Sören Frey | Florian Walker HS Mannheim SS2006 • Homepage von ACDT: http://acdt.aspectc.org • Homepage von CDT: http://www.eclipse.org/cdt Florian Walker | Sören Frey – HS Mannheim SS2006 76 5.6 Toolsupport (2) » AOP Grundlagen » Motivation Markierungen von Joinpoints im Quellcode » Das Szenario » AOP mit reinem C++ » Präprozessor Unterstützung von eigenen Make-Files » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick Für Microsoft Visual Studio® ist ein kommerzielles Add-In der Firma PureSystems erhältlich, welches den AspectC++ Compiler verwendet » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 77 Sören Frey | Florian Walker HS Mannheim SS2006 • Homepage der Firma Pure-Systems: http://www.pure-systems.de Florian Walker | Sören Frey – HS Mannheim SS2006 77 5.6 Toolsupport (3) » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick Demo » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 78 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 78 6. Weitere Ansätze (1) » AOP Grundlagen » Motivation » Das Szenario FeatureC++ » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen Spracherweiterung, welche merkmalsorientierte Programmierung mit AOP kombiniert » Schlussfolgerungen » AOP mit AspectC++ » Überblick Soll die „crosscutting concerns“ in den Merkmalen modularisieren » Funktionsweise » Szenario » Observer Pattern Verwendet AspectC++ » Generierter Code » Toolsupport » Weitere Ansätze Noch relativ am Anfang der Entwicklung (aktuell Version 0.3) » Zusammenfassung Merkmale werden durch so genannte „Mixin Layers“ konsistent zusammengeführt Kombination führt zu „Aspectual Mixin Layers“ Folie 79 Sören Frey | Florian Walker HS Mannheim SS2006 • Homepage von FeatureC++: http://wwwiti.cs.unimagdeburg.de/iti_db/forschung/fop/featurec/ Florian Walker | Sören Frey – HS Mannheim SS2006 79 6. Weitere Ansätze (2) » AOP Grundlagen » Motivation » Das Szenario XWeaver » AOP mit reinem C++ » Präprozessor » Templates » Namensräume Ermöglicht AOP mit C++ und Java » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ Kommandozeilen Tool und Eclipse Plugin verfügbar » Überblick » Funktionsweise » Szenario Version 1.0 noch nicht erreicht (aktuell 0.9.4) » Observer Pattern » Generierter Code » Toolsupport Aspekt-Code muss in einem XML-Dialekt (AspectX) geschrieben werden » Weitere Ansätze » Zusammenfassung Transformationen des Applikationscodes in XML (srcML) Weber ist in XSL implementiert Folie 80 Sören Frey | Florian Walker HS Mannheim SS2006 • Homepage von XWeaver: http://www.xweaver.org/ • Homepage von srcML: http://www.sdml.info/projects/srcml/ Florian Walker | Sören Frey – HS Mannheim SS2006 80 6. Weitere Ansätze (3) » AOP Grundlagen » Motivation » Das Szenario » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Quelle: http://www.xweaver.org/ Folie 81 Sören Frey | Florian Walker HS Mannheim SS2006 • Hierbei handelt es sich ebenso um eine „source-to-source“ Transformation Florian Walker | Sören Frey – HS Mannheim SS2006 81 7. Zusammenfassung (1) » AOP Grundlagen » Motivation » Das Szenario C++ Templates können verwendet werden, um die verschiedenen „concerns“ mit reinem C++ zu modularisieren Die fehlende Ausdrucksfähigkeit und schlechte Skalierung schränkt diese Technik ein auf » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ eine geringe Anzahl an Aspekten » Überblick » Funktionsweise » Szenario wenige Interaktionen zwischen Aspekten » Observer Pattern » Generierter Code » Toolsupport Anwendungen, die für die Verwendung von Aspekten „gut geeignet“ sind » Weitere Ansätze » Zusammenfassung Folie 82 AspectC++ am weitesten verbreitet für AOP mit C++ AspectC++ skaliert besser und ist weniger abhängig von „zweckdienlichen“ Anwendungen Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 82 7. Zusammenfassung (2) » AOP Grundlagen » Motivation » Das Szenario AspectC++ bietet eine gute Unterstützung für wieder verwendbaren und generischen Code Unterstützung für wichtige Tools ist vorhanden Verwobener Quellcode kann von bevorzugtem Compiler kompiliert werden Wenige Alternativen » AOP mit reinem C++ » Präprozessor » Templates » Namensräume » Begrenzungen » Schlussfolgerungen » AOP mit AspectC++ » Überblick » Funktionsweise » Szenario » Observer Pattern » Generierter Code » Toolsupport » Weitere Ansätze » Zusammenfassung Folie 83 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 83 Quellen (1) PUMA – The PURE Manipulator: http://ivs.cs.uni-magdeburg.de/~puma/ Homepage von AspectC++ http://www.aspectc.org/ C/C++ Development Tools http://www.eclipse.org/cdt/ AspectC++ Development Tools http://acdt.aspectc.org Pure-Systems GmbH http://www.pure-systems.de Folie 84 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 84 Quellen (2) Aspect-Oriented Software Development Community & Conference http://aosd.net/ Homepage von FeatureC++ http://wwwiti.cs.uni-magdeburg.de/iti_db/forschung/fop/featurec/ Seminar Aspektorientierte Programmierung http://myhpi.de/~nicolai/aspectc++.pdf iX 8/2001, S. 143: C++-Know-how - Teil 1-3 http://www.heise.de/ix/artikel/2001/08/143/ Aspect Oriented Software Delopment – Vorlesung FH-Ulm http://www.aosd.de/Vorlesung/SS06.html Aspekt-Orientierte Programmierung mit C++ http://www4.informatik.uni-erlangen.de/Lehre/SS03/HS_AspectOS/Ergebnisse/CppAusarbeitung.pdf Folie 85 Sören Frey | Florian Walker Florian Walker | Sören Frey – HS Mannheim SS2006 HS Mannheim SS2006 85 Danke für die Aufmerksamkeit HS Mannheim SS2006 Florian Walker | Sören Frey – HS Mannheim SS2006 86