Programowanie zorientowane aspektowo
description
Transcript of Programowanie zorientowane aspektowo
Programowaniezorientowane
aspektowoAspect-Oriented Programming
» Magdalena Tchorzewska
Ewolucja Assembler Tłumaczenie formuł (Fortran) Programowanie proceduralne Abstrakcyjne typy danych (ADT) Programowanie obiektowe (OOP) Programowanie po-obiektowe (POP):
Programowanie aspektowe (AOP) Programowanie generyczne ...
Implementacje Łatwa do zrozumienia i nieefektywna, Efektywna, lecz trudna do zrozumienia, Oparta na AOP, która jest zarówno łatwa
do zrozumienia, jak i efektywna. Eufemizm?
Implementacja dużych systemów OOP nadal nastręcza wiele trudności podczas prób modyfikacji kodu.
Czym jest AOP? Jest to rozwiązanie problemu
wynikającego z użycia wielu podobnych obiektów do interakcji z wieloma klasami w tradycyjnych systemach OOP.
Nazywa się je także związkiem przecięcia (ang. cross-cutting concern), trawersacją (ang. traversal strategy) lub po prostu aspektem.
System OOPgeneralizacja
specjalizacja
osoba
student profesor uczelnia
policz()policz()
System AOP [1]generalizacja
specjalizacja
osoba
student profesor uczelnia
policz()policz()
aspekt
System AOP [2]
„tkacz” (ang. weaver),w czasie kompilacji
kod źródłowy(poplątany kod)
Wysoki poziom,wynik implementacjimoże być różny
komponenty i opisy aspektów
(c) grimsay
System AOP [3]zwykły program
funkcjonalność
struktura
synchronizacja
komponenty
aspekt 1
aspekt 2
program AOP
Przykładowe zastosowania Rejestrowanie aktywności
użytkowników (logowanie) Rejestrowanie wystąpień błędów
(ang. error handling) Synchronizacja Optymalizacja Zarządzanie konfiguracją
aspect PointObserving {private Vector Point.observers = new Vector();public static void addObserver(Point p, Screen s) {
p.observers.add(s); }public static void removeObserver(Point p, Screen s) {
p.observers.remove(s); }pointcut changes(Point p): target(p) && call(void Point.set*(int));after(Point p): changes(p) {
Iterator iter = p.observers.iterator();while ( iter.hasNext() ) {
updateObserver(p, (Screen)iter.next()); }
}static void updateObserver(Point p, Screen s) {
s.display(p); }
}
Przykład 1
Przykład 2 Śledzenie:aspect SimpleTracing {
pointcut tracedCall(): call(void FigureElement.draw(GraphicsContext));before(): tracedCall() {
System.out.println("Entering: " + thisJoinPoint); }
}
Logowanie:aspect SetsInRotateCounting {
int rotateCount = 0;int setCount = 0;before(): call(void Line.rotate(double)) { rotateCount++; }before(): call(void Point.set*(int)) && cflow(call(void Line.rotate(double))) { setCount++; }
}
Przykład 3abstract aspect SubjectObserverProtocol {
abstract pointcut stateChanges(Subject s);after(Subject s): stateChanges(s) { for (int i = 0; i < s.getObservers().size(); i++) {((Observer)s.getObservers().elementAt(i)).update(); } }
private Vector Subject.observers = new Vector();public void Subject.addObserver(Observer obs) {observers.addElement(obs); obs.setSubject(this);}public void Subject.removeObserver(Observer obs) {observers.removeElement(obs); obs.setSubject(null); }public Vector Subject.getObservers() { return observers; }private Subject Observer.subject = null;public void Observer.setSubject(Subject s) { subject = s; }public Subject Observer.getSubject() { return subject; }
}
Co wiemy? Zmiany w każdym z aspektów są
propagowane do całego systemu podczas ponownego „tkania” kodu.
Wielkość kodu wejściowego jest nieporównywalnie mniejsza od wielkości kodu wynikowego (strukturalnego).
AOP jest rozszerzeniem dotychczas istniejących technik programowania (obiektowego).
Co dalej? Nadal jest zbyt mało wiedzy
teoretycznej na temat interakcji między aspektami a komponentami.
Czy można utworzyć kolekcję komponentów, tak by połączyć języki aspektowe w jedną całość widoczną na różne sposoby przez różne aplikacje?
Czy musimy pisać oddzielnie aspekty dla każdego języka programowania lub różnych rodzajów komponentów?
Aspectual components (AC)
Odpowiedź na brak niezależności od języka programowania.
Odpowiedź na potrzebę kontroli nad poplątanym kodem.
Łączenie funkcji i obiektów
spodziewane wymagane
modyfikacja
aplikacjapołączenia
wynik
Cechy komponentów Typowe dla klas:
Posiadają zmienne lokalne i zmienne metod
Jeden komponent może dziedziczyć od innego
Różniące się od klas: Oddzielenie komponentu/połączenia od
całości -- kod komponentu nie jest częścią aplikacji.
Rozlokowanie połączeńconnector ShowReadAccessConn1 {
Point is ShowReadAccess.DataToAccesswith { readOp = get*; }
}
connector ShowReadAccessConn3 {{Point, Line, Rectangle} is ShowReadAccess.DataToAccess with { readOp = get*; }
}
Dziedziczenie komponentów
component ShowReadWriteAccessextends ShowReadAccess {
participant DataToAccess {
expect void writeOp(Object[] args); replace void writeOp(Object[] args) { System.out.println("Write access on " +
this.toString());expected(args);
}}
}
Dziedziczenie połączeńconnector ShowReadWriteAccessConn2
extends ShowReadAccessConn3 {{Point,Line,Rectangle} is DataToAccess with { writeOp =
set*; } }
Podsumowanie AC Komplementarność w modelowaniu
współpracy pomiędzy klasami lub zachowań dla nich wspólnych
Uniwersalne zachowanie, które może być wielokrotnie wykorzystywane
Niezależne tworzenie komponentów Niezależne połączenia AC z aplikacjami Niezależne interfejsy, które mogą być
precyzyjnie zaadaptowane
Systemy wspierające AOP Demeter (C++/Java) AspectJ HyperJ Object Teams ...
LOOM.NET i WEAVER.NET (Microsoft)
Inne: http://www.aosd.net/technology/research.php
Źródła G. Kiczales, J. Lamping, A. Mendhekar, C. Maeda,
C.V. Lopes, J.M. Loingtier, J. Irwin „Aspect-Oriented Programming”
M. Mezini, D. Lorenz, K. Lieberherr „Components and Aspect-Oriented Design/Programming”
K. Lieberherr „Demeter and Aspect-Oriented Programming: Why are programs hard to evolve?”
D. Bruce, N. Exon „Alternatives to Aspect-Oriented Programming?”
http://www.parc2.com/csl/groups/sda/ http://www.ccs.neu.edu/research/demeter/ http://www.aspectprogramming.com/