piątek, 28 marca 2008

AspectJ wprowadzenie część 2

Po przeczytaniu artykułu Jacka Laskowskiego postanowiłem raz jeszcze przetestować Eclipse 3.4M na Mac OS (niestety już nie pamiętam dlaczego, ale jakiś czas temu zainstalowałem, ale coś mi nie działało tak jak miało i wróciłem do 3.3). Więc zaczynamy Eclipse 3.4M się już ściągnęło teraz Help->Software Updates dodajemy http://download.eclipse.org/tools/ajdt/34/dev/update . I podczas ściągania wtyczki jeszcze szybkie zerknięcie na Help->Tips and Tricks... tam zawsze warto zerknąć choćby żeby przypomnieć sobie skróty:) Refactor > Rename (Alt+Shift+R) i dla tych co pracują nad więcej niż jednym projektem, bardzo miłe udogodnienie Assign working sets.
Od razu stworzyłem sobie working set dla projektów aspektowych:

Dobra czas teraz wrócić do programowania aspektowego, przypuśćmy, że nasza klasa Graphic będzie tworzona przez jakąś fabrykę (która będzie pobierać dane z jakiegoś CMS). Każdy obiekt Graphic będzie zawierał informacje, czy można nim poruszać czy nie. Nasze zdanie polega na tym, żeby tak zdefiniować aspekt, że jeżeli obiekt będzie miał możliwość poruszania się to należy wykonać ciało metody move() w innym wypadku je pominąć. Rady przed (before) i po (after) metodzie były zawsze wykorzystywane przed i po wywołaniu metody, którą przecinały. Szybkie spojrzenie do dokumentacji i kogoś nam jeszcze brakuje :) rady dookoła (around), która umożliwia sprawdzenie czegoś przed wykonaniem i po, ale ma ten plus, że można w niej zdefiniować czy punkt przecięcia ma pozwolić na wykonanie ciała metody, którą przecina. Dobra zobaczmy jak to teraz wygląda w kodzie, najpierw klasa Graphic.java
public class Graphic{
private boolean isMovable = false;

public void move(){
System.out.println("Moving");
}

public static void main(String[] args) {
Graphic graphic = new Graphic();
System.out.println("Before moving");
graphic.move();
System.out.println("Change graphic to movable true");
graphic.setMovable(true);
graphic.move();

System.out.println("End");
}

void setMovable(boolean isMovable) {
this.isMovable = isMovable;
}

public boolean isMovable() {
return isMovable;
}

}


Teraz definiujemy nasz aspekt Secure.aj:
package com.itsilesia.aspects;

public aspect Secure {
pointcut checkSecure(com.itsilesia.Graphic graphic):target(graphic) && execution(* com.itsilesia.Graphic.mo*(..));

void around(com.itsilesia.Graphic graphic) : checkSecure(graphic) {
if(graphic.isMovable()){
proceed(graphic);
}else{
System.out.println("Can't move graphic");
}
}
}

Co tutaj mamy, najpierw definiujemy punkt przecięcia, który będzie uwzględniał wszystkie metody klasy Graphic które są (* com.itsilesia.Graphic.mo*(..))
- * oznacza zasięg, w naszym przypadku możemy mieć (public, private, protected i paczkowy)
- com.itsilesia.Graphic.mo*(..) punkt przecięcia nastąpi podczas uruchamiania obiektów klasy Graphic których metody zaczynają się od mo, i mogą ale nie muszą pobierać parametry
- target(graphic) definiuje, że nasz obiekt docelowy ma być typu Graphic.
Później jest nasza rada (advice) dookoła (around) która sprawdza czy dany obiekt graficzny może być poruszony. Jeśli tak to wtedy pozwala na wykonanie ciała metody którą przecina, za pomocą proceed(obiekt), w przeciwnym wypadku wypisuje komunikat o nie możliwości poruszanie obiektu. W Eclipse 3.4M uruchamiamy naszą aplikacje za pomocą Run us->Java Application rezultat poniżej:
Before moving
Can't move graphic
Change graphic to movable true
Moving
End
Teraz można sobie jeszcze wyświetlić Visualiser - AspectJ Provider Window->Open Perspective->Other...->Aspect Visualization.
Na koniec skoro jak już używa Eclipse 3.4M to dorzucam moją ulubioną wtyczkę Mylyn (download.eclipse.org/tools/mylyn/update/e3.4 )(na pewno poświecę jej jeden wpis:) )

Plan przygotowany:)

wtorek, 25 marca 2008

AspectJ wprowadzenie

Szybki start z AspectJ najpierw ściągamy wtyczkę do Eclipse 3.3 za pomocą Help->Software Updates->Find and Install.. dodajemy nowy adres http://download.eclipse.org/tools/ajdt/33/update . Potem jeszcze zapoznanie się z wprowadzającym artykułem do The AspectJ Development Tools (AJDT). W Eclipse tworzymy projekt aspektowy i klikamy Finish:
Teraz stworzymy nową klasę(ctrl + n) Graphic.java
package com.itsilesia;

public class Graphic {
public void draw(){
System.out.println("Painting");
}

public static void main(String[] args) {
Graphic graphic = new Graphic();
graphic.draw();
}
}

Teraz piszemy nasz pierwszy aspekt(ctrl +n AspectJ-> Aspect):
package com.itsilesia.aspects;

public aspect Secure {
pointcut checkSecure():execution(* com.itsilesia.Graphic.draw());

before() : checkSecure() {
System.out.println("Checking dependencies before painting");
}

after() returning : checkSecure() {
System.out.println("Exiting painting");
}

}



Najpierw zdefiniowałem punkt przecięcia (pointcut) która ma zostać użyty podczas wywołania metody draw() z klasy Graphic, później stworzyłem radę(advice) która ma się wykonać przed(before) i po(after) trafieniu na punkt przecięcia.
Teraz uruchamiamy nasz program (Run as -> AspectJ/Java Application):

Checking dependencies before painting
Painting
Exiting painting

Program zadzialal wedlug naszych oczekiwań:)
Zobaczmy co jeszcze oferuje nam Eclipse w przypadku AOP, Cross References:
można zobaczyć gdzie w naszej klasie jest użyte programowanie aspektowe i jakie rady są wywoływane. Istnieje też, cała perspektywa w Eclipse do AOP (Aspect Visualization) pokazująca powiązanie pomiędzy naszymi klasami a aspektami:

A teraz co mi daje zastosowanie AOP w tym przypadku:
- przede wszystkim odizolowanie różnych modułów (budowanie aplikacji graficznej od jej zabezpieczenia)
- bez problemowa wymiana systemu zabezpieczeń, gdyż nigdzie nie jest ona uwzględniona w kodzie obsługi obiektów graficznych
- z punktu widzenia programisty jeden drugiemu nie uprzykrza pracy dopisując jakiś niepotrzebnych linii kodu

wtorek, 18 marca 2008

AOP wstęp

Zainspirowany blogiem Jacka Laskowskiego postanowiłem zacząć opisywać moje doświadczenia związane z Java i różnymi jej aspektami. Ostatnio trafiło mi się zdanie zmodyfikowania systemu uprawnień do aplikacje do tworzenia grafiki (plakatów, ulotek, automatyzacji całego procesu drukwoania). Po krótkiej rozmowie z osobą która stworzyła już pierwszą wersje pseudo działających systemu uprawnień, okazało się, że powstało on w ciągu jednego dnia przed jakaś prezentacja produktu. A rozwiązanie polegało na tym, że wszędzie w kodzie odpowiedzialnym za wyświetlanie modelu było wstawiane
if(masz_dostep()){
rysuj();
}
niestety jak to często bywa system zaczął się rozrastać i coraz większe narzekanie na dodawanie jakiś if() . Po krótkim namyślę, postanowiłem na nowo napisać system uprawnień przy użyciu AOP.
A więc zaczynamy, definicja według Wikipedii:
Programowanie aspektowe (aspect-oriented programming, AOP) to paradygmat tworzenia programów komputerowych wspomagający separację zagadnień i rozdzielenie programu na części w jak największym stopniu niezwiązane funkcjonalnie.
W czym AOP powinno nam pomóc:
- zagadnienia przenikające ( crosscutting concerns)
- ograniczeniu powielaniu kodu
- wprowadzeniem dodatkowych zachowań za pomocą tak zwanych przecięć (pointcuts)
- możliwość sprawdzenia pewnych warunków przed wywołaniem metody jak i po, oraz przechwycenie wyjątku jeśli takowy metoda rzuca
Najważniejsze pojęcia z AOP a później już tyko praktyka (AspectJ):
- przecięcia (pointcuts) określają punkty złączeń dla których należy stosować poszczególne rady (advices)
- rada (advice) określa co należy zrobić w punkcie złączenia, rada jest z reguły definiowana w obiektach przechwytujących metody (method interception)
- inter-type declarations - pozwalają programiście na zmianę statycznej struktury i relacji pomiędzy klasami
- aspects - jednostka modularyzacji dla zagadnień przenikających
Po krótkim wstępie w następnej części już praktyka na podstawie AspectJ.