Aspektorientierte Programmierung in C++

Werbung
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
Zugehörige Unterlagen
Herunterladen