Aspektově orientované programování

Aspektově orientované programování ( AOP ) je paradigma programování pro objektově orientované programování , aby bylo možné používat obecné funkce napříč několika třídami ( průřezové zaměření ). Logické aspekty jako aplikačního programu jsou odděleny od skutečné obchodní logiky. Typickými příklady aplikací jsou správa transakcí , auditovatelnost a chování protokolování .

Koncept AOP vyvinul Gregor Kiczales a jeho tým ve společnosti Xerox PARC . V roce 2001 zde byl představen také první jazyk AOP AspectJ .

motivace

Software v zásadě musí splňovat určité úkoly / požadavky. Tyto požadavky lze zhruba rozdělit do dvou oblastí:

  1. Tzv. Obavy na základní úrovni (týkají se logického „jádra“ aplikace) nebo funkční požadavky. Jedná se o požadavky na software, který lze obvykle snadno zapouzdřit do jednotlivých funkcí. Příkladem může být výpočet hodnoty.
  2. Tyto problémy na úrovni systému (vliv na celý systém) nebo technické okrajové podmínky. Tyto požadavky nelze jednoduše zapouzdřit, protože je nutné je implementovat na mnoha místech. Ukázkovým příkladem toho je protokolování , záznam toku programu do souborů protokolu. Vyvolání záznamníku není pro skutečnou funkčnost nutné, ale stále musí být integrováno do zdrojového kódu. Dalším příkladem může být transakce přístupů ke zdroji, jako je B. databáze.

Tyto dvě části jsou protkané. Problémy na základní úrovni lze označit jako komponenty a aspekty na systémové úrovni jsou aspekty. Problémy na základní úrovni jsou obvykle implementovány jako moduly nebo objekty . Před aspektově orientovaným programováním neexistovalo pro tyto aspekty žádné elegantní řešení.

Problém propletených požadavků se také označuje jako průřezové problémy , protože „prořezávají“ všechny logické vrstvy systému. AOP je nástroj, který také fyzicky odděluje logicky nezávislé koncerny. Cílem je vygenerovat kód, který se snáze udržuje a je opakovaně použitelný .

V této souvislosti však nelze obavy na úrovni systému srovnávat s čistě technickými zájmy. Technické problémy jako např B. zavedení samostatného specializovaného autorizačního systému pro uživatele může mít jistě aspekt aspektu.

Pozadí

V historii vývoje programovacích jazyků byly znovu a znovu vyvíjeny nové programovací koncepty a jazyky na vysoké úrovni, které je implementují, počínaje programováním v assembleru , který nahradil přímé programování v binárním kódu , přes procedurální a funkční programování, až po dnešní objektově orientované jazyky. Účelem je usnadnit vývojářům práci a dosáhnout tak vyšší efektivity při vývoji softwaru. Jedním ze základních principů, které byly použity u všech nových programovacích konceptů, bylo zapouzdření funkčnosti.

Povolení rozšířené funkce není cílem tohoto vývoje, protože každý jazyk vysoké úrovně je po kompilaci mapován na strojový kód.

Zapouzdření funkcí zejména usnadňuje vývoj softwaru zvýšením udržovatelnosti a opětovného použití stávajících programových kódů. Jak se software postupem času stává stále složitějším a rozsáhlejším, což činí vývoj časově náročnějším a dražším, tyto dva cíle jsou stále důležitější a jsou nyní ústředními prvky ve vývoji nových programovacích konceptů a jazyků.

AOP (aspektově orientované programování nebo aspektově orientované programování) je programovací koncept, který se zabývá problémem tzv. Průřezových problémů .

Nákladově efektivní a včasný vývoj a údržba vysoce kvalitního softwaru je primárním cílem softwarového inženýrství . K dosažení tohoto cíle je nezbytný software, který je co nejvíce modulární s co nejmenší složitostí modulů.

V konvenčním systému, který zahrnuje také objektově orientované přístupy, lze základní funkce, anglické základní záležitosti , úhledně rozdělit do modulů podle pravidel v oboru. Existují však obavy (obavy, obavy, požadavky), jako je zpracování chyb, výkon a zabezpečení v každém systému, které překračují základní funkce, a proto je nelze jasně přiřadit softwarovému modulu. Výsledkem je, že fragmenty těchto průřezových obav (funkce průřezového jádra (zastřešující požadavky) - nedostatek soudržnosti ) nejsou přiřazeny a jsou rozptýleny v celém kódu nezakapsulovaným způsobem. Tyto průřezové základní funkce zabraňují správné modularizaci v konvenčních softwarových systémech a zhoršují údržbu, srozumitelnost, opakovanou použitelnost a (sledovatelnost). V běžných programovacích jazycích, systém rozklad je za to zodpovědný , který umožňuje pouze jeden rozměr - seznam funkcí. Tento jev se také nazývá dominantní rozklad . Jinými slovy, přirozeně multidimenzionální problém musí být řešen jednorozměrně.

Odvození od předchozích paradigmat

V procedurálním programování je provádění kódu relativně lineární. Sledováním symbolů lze každý jednotlivý krok programu sledovat přímo, i když se díváte na subsystém. Příklad v C :

void function (void * c)
{
    Component_repaint(c);
}

Funkce Component_repaint()je jasná. Bez ohledu na to, zda má ukazatel cdynamický Componentnebo odvozený typ, je vždy Component_repaint(Component*)volána stejná funkce ( statické psaní ).

V objektově orientovaném programování je sledovatelnost snížena polymorfismem . Příklad v Javě :

void function (Component c)
{
    c.repaint();
}

Není jasné, která repaint()metoda se provádí, záleží na skutečném typu objektu, na který se codkazuje. ComponentTyp odvozený z mohl repaint()definovat své vlastní metodu přepsání metody Component zděděnou od repaint().

V aspektově orientovaném programování je sledovatelnost dále snížena pomocí bodových řezů . Pointcut obsahuje kód, který má být proveden Aby připojit bod , je spojit bod je přesně definované události volání. Zde lze aktivovat rady téměř pro jakékoli místo v řetězci volání . V extrémních případech je dokonce možné zabránit volání metod function()nebo repaint()samotných. Lze si tedy představit aspekt, který definuje radu pro spojovací bod „zavolat metodu function()“, která výslovně zakazuje další zpracování tohoto volání funkce. V doporučení můžete také určit, že místo objektu by měla být pro objekt použita jiná metoda . Informace o tom, co by se mělo stát dále, nelze zpočátku odečíst na místě samotné události. repaint()

Srovnání

Abyste lépe porozuměli pojmům bodových řezů , spojovacích bodů a rad, podívejte se níže na srovnání se staršími paradigmy

  • Structured Query Language ( SQL )
    Představte si příkaz SELECT, který dokáže vybrat všechny metody ve všech třídách systému. V této souvislosti
    - na pointcut části v WHERE klauzule, která omezuje počet vybraných metod
    - A spojit bod odpovídá výsledku vyhledávání specifické ve smyslu záznamu dat z databáze - pouze to, že žádné datové záznamy jsou vybrány z databáze, ale metody v systému
    - rada je pak metoda v jednom aspektu, která má být provedena před, po nebo namísto vybrané metody.
  • Další paradigmata programování
    Zatímco v procedurálním programování je sledovatelnost zajištěna fragmentem zdrojového textu a v objektově orientovaném programování s dalšími znalostmi typů runtime, sledovatelnost v aspektově orientovaném programování vyžaduje znalost všech aspektů, bodové řezy pro spojovací body Definujte fragment kódu.
    Ortogonální zde znamená, že vlastnosti metod jsou definovány „kolmo“ na normální směr programování. Skutečné provedení kódu není definováno pouze hierarchií volání a typů, ale také „kolmo“ (ortogonálně) na něj aspekty.

analogie

Princip lze vizualizovat následovně: program, bez ohledu na to, zda je procedurální nebo objektově orientovaný, sleduje vývojový diagram programu , tj. H. tok programu je definován v každém bodě lineárními sekvencemi instrukcí ( bloky kódu ) a skoky mezi nimi (např. volání metod). Jeden aspekt by zde byl stejně jako šablona, ​​která je umístěna nad tímto původním plánem a provádí různé změny nebo doplňky vývojového diagramu. Změny šablony ponechají původní plán beze změny, šablonu lze kdykoli vyměnit, zkombinovat s ostatními nebo znovu odebrat.

Technická úvaha

V objektově orientovaném běhovém prostředí lze stranově orientované programování umožnit proměnlivými skokovými vektory . Lze to považovat za druh „záplatování“ funkcí stanovených v programovacím paradigmatu.

Objekt C je povolen pro sledování interakcí mezi dvěma objekty A a B, aniž by byly nutné změny nebo rozšíření A a B. Samozřejmě je nutná změna v A nebo B nebo v obou. AspectJ vytváří tyto změny automaticky, proces, jak toho dosáhnout, se nazývá tkaní , protože uvedené změny jsou před kompilací „vpleteny“ do původního kódu.

Oblasti použití

Aspektově orientované programování dokáže zcela nahradit programování řízené událostmi (zpracování událostí) dříve používané v objektově orientovaném programování . Programování řízené událostmi se používá k upozornění objektu X na změny objektu Y. Objekt Y nepotřebuje znát objekt X. Předchozí řešení je zde vysvětleno na příkladu okna v Javě (java.awt.Frame). Události, ke kterým dochází konkrétně pro Windows a o kterých má být upozorněna jiná část programu, zahrnují zavírání, aktivaci a deaktivaci. Rozhraní java.awt.event.WindowListener pro to definuje různé metody a musí být implementováno objekty, které chtějí být upozorňovány na změny okna. Objekty, které chtějí být upozorněny, se musí zaregistrovat u příslušného jiného objektu.

Díky programování orientovanému na aspekty může být definice takových rozhraní nadbytečná. Aspekt X definuje události kódu, které mají být monitorovány přesně pro objekt Y, který má být monitorován, nazývaný bodový řez, složený ze spojovacích bodů (celá metoda, volání metody, návrat metody, rozlišitelné na návrat metody s návratovou hodnotou a návrat metody s výjimkou) a definuje doporučení pro různé bodové řezy, tj. kód, který se má provést. Provádění kódu v X prostřednictvím změn objektu Y proto může probíhat bez dalších rozhraní, metod a registračních mechanismů.

Aspektově orientované programování lze použít při vývoji frameworků (knihoven) např. B. implementovat vlastnosti, jako je vytrvalost nebo synchronizace. Mechanismus přenosu pak zůstane uživateli knihovny skrytý. Skrytí mechanismu přenosu v tomto případě dělá kód jasnější, protože metody nejsou přetíženy rámcovým kódem.

Další oblastí aplikace je testování softwaru, kde zavedení nových atributů ve třídách beze změny jejich zdrojových textů (mezidruhové deklarace) představuje nové a zajímavé možnosti pro vývoj testů white box, např. B. sledovat soukromé atributy.

Joinpoint vs. Stín joinpoint

Je třeba rozlišovat mezi body spojení a takzvanými stíny bodů spojení. Stín bodu spojení je statický výskyt potenciálního bodu spojení. Zda se tento stín (např. Volání metody ve zdrojovém kódu) skutečně stane spojovacím bodem, se rozhoduje pouze za běhu, v závislosti na odpovídajícím pointcut (nebo označení pointcut).

Bodový řez definuje sadu stínů joinpoint, které vyřízne ze základního programu. Pokud je zadán stín spojovacího bodu za běhu programu a lze splnit jeho definiční bodový řez, stane se „stín spojovacího bodu“ „spojovacím bodem“.

příklad

Následující příklad vysvětluje základní myšlenku aspektově orientovaného programování. Použitým programovacím jazykem je AspectJ , který rozšiřuje Javu o orientaci na aspekt.

Úvodní příklad

Jako úvodní příklad poslouží standardní úkol ve vývoji softwaru: trasování informací do souboru. Procedura bez aspektově orientovaného programování spočívá ve vytvoření záznamníku a volání tam odpovídající metody, která uloží skutečné informace do souboru protokolu:

public void eineMethode() {
    logger.trace("Betrete \"eineMethode\"");

    // Abarbeitung der Methode
    m = a + 2;

    logger.trace("Verlasse \"eineMethode\"");
}

Na začátku metody se do záznamníku odešle zpráva, že se zadává metoda. Poté následuje skutečná logika metody. Nakonec je protokolován výstup z metody.

V typické aplikaci jsou taková volání metod do záznamníku k dispozici v mnoha metodách a třídách - jsou rozptýlena po celé aplikaci a v žádném případě nejsou modulární. Záznamník musí

  • - oznámeny každému předmětu a
  • nelze snadno vyměnit v centrálním bodě - alespoň ne bez deklarace v systému veřejnou statikou, která se rovná globální proměnné, a tedy pochybnému designu.

To také objasňuje, co se rozumí významově a fyzicky nezávislými částmi programu . Ve výše uvedené metodě jsou smíchány dva skutečně nezávislé úkoly. Toto je na jedné straně logování a na druhé straně skutečná logika metody, která spočívá v uložení výsledku sčítání do členské proměnné m .

Aspektově orientované programování nyní také umožňuje modularizovat úkoly, jako je trasování. Předpokládejme, že chcete zaznamenat vstup a výstup každé metody ve třídě, jak je uvedeno výše. Ve srovnání s konvenčním programováním lze takovou instrukci formulovat přímo jako aspekt v AOP :

public aspect Tracing {
    pointcut traceCall():
        call(* AOPDemo.*(..));

    before(): traceCall() {
        System.out.println("Betrete \"" + thisJoinPoint + "\"");
    }

    after(): traceCall() {
        System.out.println("Verlasse \"" + thisJoinPoint + "\"");
    }

}

Aspekt určuje, že mají být zahrnuty všechny metody třídy AOPDemo bez ohledu na jejich podpis . Úkoly jsou odděleny tímto způsobem a původní metoda může být napsána ve zkrácené formě:

public void eineMethode() {
    // Abarbeitung der Methode
    m = a + 2;
}

Další příklad

Programování orientované na aspekt navíc umožňuje přesměrování původní programové sekvence. Aspekty zabezpečení mohou například nahradit původní sekvenci programu, aby se zabránilo neoprávněnému přístupu k chráněným částem programu. Aspekty ukládání do mezipaměti zvyšují rychlost provádění programů a používají se ke snížení nutnosti vyvolání složitých částí programu, jako je přístup k databázi nebo systému souborů. Následující příklad ukazuje přesměrování volání metod nebo výměnu částí programu jako odposlech kolem rady:

public aspect Caching {

    pointcut cacheCall():
        call(* AOPDemo.*(..));

    private Map cache = new Map();

    around(): cacheCall(Joinpoint joinPointContext) {

       // Prüfen, ob Rückgabewert für aktuelle Aufruf-Argumente schon im Cache abgelegt wurde
       Object args = joinPointContext.getArguments();
       boolean isCallCached = cache.containsKey(args);

       if (isCallCached) {
             // Umleitung und Austausch des ursprünglichen Methodenaufrufs, gesicherten Rückgabewert aus Cache verwenden
             Object cachedReturnValue = cache.get(args);
             return cachedReturnValue;
       }
       else {
             // Weiterleitung an ursprüngliche Methode und neuen Rückgabewert im Cache sichern
             Object newReturnValue = joinPointContext.proceed();
             cache.put(args, newReturnValue);
             return newReturnValue;
       }
    }
}

Podmínky

Příklad již obsahuje nejdůležitější koncepty, pokud ne všechny. V této části jsou chybějící přidány a přiřazeny k pojmům použitým v AOP.

Pro tento účel je příklad rozšířen o následující sekvenci kódu a předchozí sekvence je zobrazena graficky:

public void quellMethode() {
    eineMethode();
}

Schematické znázornění použití aspektu

Aspekt vstupuje do hry ještě předtím, než jeden eineMethode()vstoupí. Důvodem je spojovací bod přímo před ním. Tyto body spojení jsou uvedeny implicitně. To znamená, že jsou přítomny před každou metodou. Vzor, který vybírá ty spojovací body ze všech existujících spojovacích bodů, které jsou zajímavé pro určitý aspekt, se nazývá bodový řez . Ve skutečnosti jsou bodové řezy vzory, které také umožňují zástupné znaky . Aby bylo možné určit, kdy má být kód v rámci aspektu spuštěn, vstupují do hry rady . V úvodním příkladu jsou to před a po , v dalším příkladu kolem . Tyto rady jsou mimo jiné poskytovány implicitně.

Programování s aspekty také umožňuje změnit chování tříd v aspektech. Aspekty mohou do tříd přidávat pole a metody. I zde je možné použít zástupné znaky pro několik tříd současně. V jazyce, jako je Java, tato intertypová prohlášení porušují pravidlo, že všechna pole a metody třídy lze najít v jednom souboru nebo hierarchii dědičnosti třídy, protože její aspekty nepatří.

Typické úkoly

AOP je zvláště vhodný pro programování takzvaných průřezových podniků . Mezi příklady patří protokolování , zpracování chyb , vytrvalost , ověření dat a zabezpečení IT .

Profilování API, jako jsou ty obsažené v Javě , fungují podobně jako AOP. Používají se k určení nevýkonných kódů. Za tímto účelem se měření času pro zpracování všech metod provádí pomocí takzvaného profileru. Skutečný profiler může být informován virtuálním strojem při zadání a ukončení metody. Profilovač lze proto implementovat také s aspektově orientovaným programováním.

Podobné přístupy

Aspekty mají původ v objektově orientovaném programování a jsou přinejmenším ve svém úmyslu srovnatelné s protokoly metaobjektů, jako jsou například ty, které se nacházejí v systému Common Lisp Object System . Aspekty dále souvisejí s koncepty, jako je předmětově orientované programování , mixiny , třídní schránky nebo koncept delegování , které lze nalézt v programovacím jazyce Self . Takzvané vlastnosti představují podobný nebo dokonce ekvivalentní přístup .

Poznámky

Výhodou orientace na aspekt je logické a fyzické oddělení sémantiky (komponenty) od technického detailu (aspektu). Nevýhodou aspektově orientovaného programování je režie, která vzniká po tkaní v generovaném programu. To obecně vede ke ztrátě výkonu . Kromě toho aspektově orientované programování snižuje sledovatelnost chování programu, protože místa, za která je aspekt zodpovědný, nejsou v příslušném kódu přímo rozpoznatelná. Ladění je mnohem obtížnější, ale tuto nevýhodu lze neutralizovat nebo alespoň snížit podporou IDE , protože ladění je stejně multidimenzionální jako vývoj kódu.

Další nevýhodou je, že při použití této techniky mohou nastat nežádoucí a obtížně pochopitelné interakce mezi jednotlivými aspekty.

Aspekty a komponenty lze definovat v různých programovacích jazycích.

Viz také

literatura

  • Lars Wunderlich: AOP: Aspektově orientované programování v praxi. Developers.press, Frankfurt am Main 2005, ISBN 3-935042-74-4 .
  • Oliver Böhm: Aspektově orientované programování s AspectJ 5: Začínáme s AspectJ a AOP. Dpunkt Verlag, Heidelberg 2006, ISBN 3-89864-330-1 .
  • Renaud Pawlak, Lionel Seinturier, Jean-Philippe Retaille: Základy AOP pro rozvoj J2EE (nadace). Apress, Berkeley CA 2005, ISBN 1-59059-507-6 .
  • Ralf Westphal: Aspektově orientované programování s .NET. In: dotnetpro Ulm 22.2007,10. ISSN  1610-1553

webové odkazy

Individuální důkazy

  1. ^ Zachycení kolem rady