Občasník názorů jedné karkulky

Aspektově orientované programování

Již se mi několikrát poštěstilo, že se mě někdo zeptal, jaké mám téma diplomky…  Tak jsem jim to řekl a oni mi opravdu upřímně poděkovali :) A abyste toho nebyli ušetřeni ani vy, kteří jste to štěstí ještě neměli, podělím se s vámi o malý kousíček toho, co píšu. Myslím, že si tím ušetřím spoustu zbytečných dotazů ;) Takže abyste věděli, to co se tu teď objevuje, je technologie, kterou využívám ve své diplomové práci. Jmenuje se Aspect Oriented Programming, neboli aspektově orientované programování, výhodně má stejnou zkratku v češtině i v angličtině, a to AOP.


Aspektově orientované programování

Co je aspektově orientované programování?

Aspektově orientované programování (dále jen AOP) je technika, která vznikla přibližně před 10 lety. Je nadstavbou objektově orientovaného programování a umožňuje snáze naprogramovat některé často se opakující činnosti. Není alternativou k OOP, ale naopak komplementem. OOP se k některým potřebám příliš nehodí a proto je nad ním AOP, které tyto potřeby dokáže snadno naplnit. AOP se začalo hodně používat zejména od r. 2004.

Cílem AOP je nahradit v kódu opakující se činnosti, nejsnadněji to je možné ukázat na logování. V případě, že chceme logovat například před a po provedení některých metod, musíme před každou a po každé zapsat kód pro logování a není snadné ho potom měnit.

Ještě než budeme pokračovat, je ale potřeba definovat několik termínů, které budeme dále používat:

  • Joinpoint – místo, kam je možné vložit do kódu další logiku pomocí AOP, patří sem jako nejčastěji používané volání metody, nebo spuštění metody, či inicializace třídy apod.
  • Advice – kód, který je spuštěn v určitém joinpointu, existuje více druhů advice, např. before (spouští se před joinpointem) nebo after (za joinpointem)
  • Pointcut – je souborem joinpointů, pro které je spouštěna stejná advice, díky granularitě umožňuje snadnou kontrolu nad spouštěním AOP kódu
  • Aspect – je kombinací advice a pointcut, určuje tedy logiku, která je do aplikace vložena a místo, kde bude spuštěna
  • Weaving – proces vkládání aspektů do aplikace
  • Target – cíl, objekt, jehož chování je ovlivněno nějakým AOP kódem

Typy AOP

Existují dva typy AOP, statické a dynamické. Statické AOP poskytuje například AspectJ, dynamické např. Spring Framework. Implementací AOP existuje velké množství, nejstarší z nich je právě AspectJ.

Statické AOP

Při statickém zpracování probíhá weaving při buildu aplikace, přibývá zde další krok. Díky tomu je statické AOP rychlejší než dynamické, kód AOP ale nelze měnit za běhu aplikace, není možné přidávat či odebírat funkčnost za běhu. Jakákoliv změna v AOP tedy nutí k opětovné kompilaci celé aplikace. Příkladem využití statického AOP je právě AspectJ.

Dynamické AOP

U dynamických implementací AOP probíhá weaving proces za běhu aplikace. Toho je dosaženo u různých implementací pomocí různých technik, nejčastěji se ale používají proxy pro každý objekt, který využívá aspekty. Nevýhodou je nižší výkon oproti statické implementaci, výhodou možnost měnit AOP kód úplně nezávisle na aplikaci, změny v AOP tedy nutně neznamenají potřebu opětovné kompilace celé aplikace. Dynamické AOP využívá například Spring Framework.

Příklad využití AOP

Ukážeme si nyní na jednoduchém příkladu, v jakém případě je efektivní AOP využít. Příklad bude uveden v programovacím jazyku Java za využití jak AspectJ, tak Spring AOP, abychom prezentovali rozdíly mezi implementacemi statickými a dynamickými.

Poznámka: Tento příklad je pouze pro ilustrační účely, stejného výsledku bychom v tomto případě mohli docílit pomocí mnohem jednodušších metod.

 

Základem je třída, která na obrazovku vypíše text „Ahoj Karle!“.

 

package aopPrikladSpring;

 

public class PisatelZpravy {

     

      public void napisZpravu() {

            System.out.println("Ahoj Karle!");

      }

}

To je jednoduchá třída, která pomocí klasického výstupu vypíše jednoduchý text. Nyní budeme chtít, aby při každém vypsání zprávy program uživatele pozdravil „Dobrý den“, pak vypsal zprávu a na konec se rozloučil „Nashledanou“. Znamená to, že budeme používat Advice, která bude vypisovat kód před spuštěním metody napisZpravu a po jejím spuštění, joinpointem je zde tedy spuštění metody. První třída je stejná jak pro AspectJ tak pro Spring AOP, jen náleží do jiné package.

Spring AOP – vylepšovač

package aopPrikladSpring;

 

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

 

public class VylepsovacZpravy implements MethodInterceptor {

 

      public Object invoke(MethodInvocation invocation) throws Throwable {

            System.out.println("Dobrý den");

            Object navrat = invocation.proceed();

            System.out.println("Nashledanou");

            return navrat;

      }

}

Další třída nám vypíše právě zprávy „Dobrý den“ a „Nashledanou“, které potřebujeme. Implementuje standardní rozhraní, které zavedla AOP Alliance (http://aopalliance.sourceforge.net/). Objekt MethodInvocation se stará právě o spouštění metody, okolo které chceme doplnit advice.

AspectJ – vylepšovač

 

package aopPrikladAspectJ;

 

public aspect VylepsovacZpravy {

 

      pointcut zavolejVypisZpravy() : call(public void PisatelZpravy.napisZpravu(..));

     

      before() : zavolejVypisZpravy() {

            System.out.println("Dobrý den");

      }

     

      after () : zavolejVypisZpravy() {

            System.out.println("Nashledanou");

      }

}

Tento soubor nazveme VylepsovacZpravy.aj, určuje nám logiku vkládání aspektu do kódu. Nejprve se pomocí klíčového slova pointcut určí místo, kam bude aspekt vložen a pak se před (before) a za (after) volání metody napisZpravu vloží další kód.

Spring AOP - hlavní třída

 

package aopPrikladSpring;

 

import org.springframework.aop.framework.ProxyFactory;

 

public class DobryDenAOPPrikladSpring {

     

      public static void main(String[] args) {

            PisatelZpravy cil = new PisatelZpravy();

           

            // vytvoříme proxy

            ProxyFactory pf = new ProxyFactory();

           

            pf.addAdvice(new VylepsovacZpravy());

            pf.setTarget(cil);

           

            PisatelZpravy proxy = (PisatelZpravy) pf.getProxy();

         

            // vypíšeme zprávu

            proxy.napisZpravu();

      }

}

 

V hlavní třídě aplikace vytvoříme nejprve instanci pisatele a potom proxy tohoto cílového objektu. Ještě před vytvořením proxy přidáme advice vylepšovač pomocí metody addAdvice. Dále metodou setTarget nastavíme cílový objekt (PisatelZpravy). Pomocí metody getProxy vytvoříme proxy a nyní již můžeme volat metodu napisZpravu. Výsledek vypadá takto:

Dobrý den

Ahoj Karle!

Nashledanou

AspectJ - hlavní třída

 

package aopPrikladAspectJ;

 

public class DobryDenAOPPrikladAspectJ {

 

      public static void main(String[] args) {

            new PisatelZpravy().napisZpravu();

      }

}

V hlavní třídě již jen vytvoříme instanci pisatele a spustíme metodu napisZpravu. O zbytek se postará logika AspectJ. Výsledek vypadá takto:

Dobrý den

Ahoj Karle!

Nashledanou

 

A to je pro dnešek vše :) Jakékoliv dotazy směřujte prosím do komentářů :) 

 

Sdílet

Komentáře

seily Týýýjo, je fakt vidět, že tomu asi rozumíš:-DDD..............
Jen tě asi budu muset poprosit ještě o nějaký podrobný slovník tohoto jazyka, který je asi mimo mě:-)....
Ale bude to asi tak lepší, když i mimo zůstane;-)...
Nééé, chceš titul, tak to tak jendoduchý mát nebudeš, jestli přibydou další podobné články, nechám si to osobně vysvětlit:-D......
Acho,škoda, že sme se nevsadili.......

Pavel icepoint Trávníček to vypada zajimave :) jen zatim nevim, kde bych to vyuzil ... znas nejaky zpusob, jak to vyuzit treba v php ? asi tezko co ...

sqdw Icepoint: pro php existuje několik implementací, vývoj se ale u všech už aspoň rok nepohnul, ono ani OOP se v php pořád moc nevyužívá...
Každopádně buď http://www.aophp.net/ nebo http://phpaspect.org/, taky se k tomu dají najít dvě třídy na phpclasses.org

Pavel icepoint Trávníček diky :)

Pro přidání komentáře se musíš přihlásit nebo registrovat na signály.cz.

Autor blogu Grafická šablona Nuvio