Această întrebare ma făcut să mă gândesc la modalități eficiente de a aplica AOP în unele sisteme software cu care am lucrat. De asemenea, mi-am dat seama că trebuie să vă gândiți cum și când să începeți să utilizați metode noi, mai ales dacă au nevoie de noi moduri de gândire. AOP, care a fost menționat mai devreme în acest articol, reprezintă doar o nouă abordare. Aș dori să vorbesc puțin despre metodele de utilizare eficientă, în opinia mea, a AOP. De asemenea, vom analiza unele realizări recente în AOP, care pot facilita înțelegerea sa.
Ca exemplu, limbajul orientat spre aspect Java va fi folosit. În prezent, există mai multe limbi de programare cu o implementare orientată spre aspect. Printre acestea se numără AspectC ++ și chiar AspectL, adică implementarea orientată spre aspect a Lisp. 1
Prezentare generală a conceptelor AOP
Pentru a înțelege această discuție despre AOP, este necesar să cunoaștem mai multe concepte. Conceptul de bază este punctul de legătură. Acest concept, la care toți programatorii sunt familiarizați și pentru care nu există niciun nume. Un punct de asociere este un "punct precis definit în procesul de executare a unui program". 3 Există multe tipuri de puncte de conexiune, de exemplu, o metodă de apel sau returnare, care poate fi o revenire normală sau generarea unei excepții.
În AOP, trebuie să găsiți o modalitate de a identifica punctele de conectare din program. În AspectJ, un punct punct este folosit pentru a descrie unul sau mai multe puncte de conectare. Pointcut este o expresie care descrie un set de puncte de conectare. Punctul-cheie poate fi considerat o cerere la cod, care returnează un set de puncte de conectare.
Când selectați un set de puncte de conectare, este prevăzut un mecanism de consiliere. Sfat este un cod executabil care se execută la atingerea punctului de conexiune în timpul executării programului. Punctele de conexiune, punctele de punctaj și sfaturile sunt concepute pentru a implementa proprietățile dinamice ale software-ului. Mecanismul de consiliere modifică caracteristicile codului executabil al programului.
Exemple de AOP
Acum, ia în considerare exemple în care puteți utiliza AOP și unde este utilizat. Unele exemple sunt luate din sistemele de producție, altele sunt din procesul de operare și dezvoltare. Să începem cu câteva exemple pentru dezvoltatori.
Urmărirea execuției
Este uimitor câte dezvoltatori introduc în cod codul pentru a depana sau a urmări execuția programului. Pentru debugeri, aceste informații sunt valide. Dar această discuție nu are legătură cu studierea programelor de depanare. Firește, există argumente puternice pentru crearea unei urme de text a programului. În setul actual de instrumente de dezvoltare AspectJ (AJDT) din Eclipse, există un exemplu perfect de aspect care implementează urmărirea execuției programelor. Exemplul este descris în detaliu în sistemul de ajutor Eclipse. Acesta poate fi găsit și în Ghidul de programare AspectJ.
În exemplu, există o mică aplicație Java cu clase reprezentând forme bidimensionale, de exemplu, cercuri și pătrate. Aplicația are, de asemenea, o metodă care creează două cercuri și un pătrat și afișează proprietățile acestora, de exemplu, aria, perimetrul și distanța dintre centre. După pornirea programului, ieșirea trebuie să corespundă cu figura 1.
Figura 1. Datele din formularul programului
Puteți lua în considerare secvența efectivă a apelurilor metodice în două moduri. În prima abordare, puteți introduce codul la începutul fiecărei metode care trimite un mesaj cu numele metodei și clasei, precum și faptul de a apela această metodă. Acest lucru trebuie făcut pentru fiecare metodă. A doua abordare este de a crea un aspect care să efectueze aceeași operație. În această abordare, nu este necesar să modificați codul aplicației.
Un exemplu de trasare constă în mai multe versiuni ale unui program de urmărire folosind aspecte. Luați în considerare ultima versiune. Pentru alte versiuni, consultați Ghidul de programare AspectJ.
Soluția pentru un mecanism sigur de urmărire constă din două fișiere. Primul fișier este un aspect abstract. Acest aspect este similar cu o clasă abstractă în care un anumit cod este lăsat programatorilor pentru implementare într-o clasă derivată sau, în acest caz, într-un aspect derivat. Un aspect abstract, numit Trace, are câteva metode standard pentru transmiterea mesajelor despre intrarea și ieșirea dintr-o metodă sau constructor și despre formatarea datelor de ieșire. Dacă aspectele nu sunt utilizate, aceste metode se află în clasa de ajutor și sunt utilizate pentru a afișa informații de urmărire. Urmărirea permite, de asemenea, programatorilor să precizeze tipul de urmă urmând setarea proprietății TRACELEVEL. Există trei niveluri: fără mesaje, mesaje care nu sunt structurate și mesaje structurate pentru a afișa apeluri imbricate.
Urmărirea definește trei puncte punctuale: două concrete și una abstractă (a se vedea figura 2). Orice aspect care extinde aspectul Trace trebuie să furnizeze o punctură abstractă, myClass. Scopul punctului este de a selecta clasele pentru obiectele care conțin puncte de conexiune care vor fi recomandate. Acest lucru permite dezvoltatorilor să decidă ce clase ar trebui incluse în datele de urmărire a rezultatelor.
Figura 2. Punctul de vedere în ceea ce privește urmărirea
Pointcut myConstructor selectează punctele de conexiune la începutul fiecărui constructor pentru obiectul din clasă pe care mi-a selectat-o MyClass. Punctul de joncțiune este de fapt corpul designerului. myMethod este similar cu myConstructor, dar selectează executarea oricărei metode în clasa selectată. Rețineți că executarea metodei toString este omisă, deoarece este utilizată în codul de consiliere.
Aspectul codului de consiliere este destul de simplu. Există un cod de sfat introdus înaintea fiecărui punct de conectare și sfaturi care sunt executate după punctul de conectare. Acest lucru este prezentat în figura 3.
Figura 3. Punctaj în aspectul urmei
Pentru a utiliza aspectul Trace, trebuie să îl extindeți și să oferiți o implementare exactă pentru punctul de punctaj abstract. Figura 4 prezintă corpul programului de probă cu aspectul TraceMyClasses. Punctul cheie este folosit pentru a selecta numai acele obiecte care sunt instanțe de clase TwoDShape, Circle sau Square. Metoda principală stabilește TRACELEVEL, inițializează traseul de execuție al programului și pornește metoda principală a exemplului.
Figura 4. Un aspect particular al traseului
Figura 5 prezintă o parte din ieșire pentru acest exemplu. Rețineți că informațiile despre toate obiectele sunt afișate. Aceasta face parte din metoda toString a fiecărui obiect. Pointcut (o secțiune punct) myClasses publică un obiect în sfaturi (recomandare), ceea ce face ușor să adăugați informații despre obiect.
Figura 5. Exemplu de date de urmărire a ieșirii
Care sunt avantajele trasării AOP în comparație cu introducerea manuală a codului de urmărire în locurile potrivite? Există mai multe avantaje.
- Toate codurile sursă asociate cu relația de urmărire sunt stocate într-un singur loc (două aspecte);
- Codul de urmărire este ușor de inserat și șters. Pentru aceasta, aspectele sunt eliminate din configurația structurii;
- Codul de urmărire poate fi adăugat în orice locație, chiar dacă se adaugă noi metode la clasele vizate. Acest lucru vă permite să eliminați erorile programatorului. Dacă ștergeți un aspect din configurația designului, puteți fi sigur că toate codurile de urmărire sunt șterse și nimic nu lipsește;
- Avem un aspect reutilizabil care poate fi aplicat și îmbunătățit.
Programe contractate sau securizate
Atunci când se creează biblioteci de largă utilizare, nu se poate asigura siguranța argumentelor transmise metodelor. Este necesar să se testeze argumentele înainte de a fi procesate de logica fiecărei metode. Acesta este un exemplu de programare sigură. Se presupune că toate erorile posibile vor fi tratate grațios.
Să creăm un aspect pentru verificarea tuturor argumentelor în metodele publice. Mai întâi de toate, vom crea o punctură. Vom folosi punctul de introducere myClass din exemplul anterior și vom adăuga un punct pentru a selecta constructorii care trebuie să testeze argumentele și o metodă de distanță care nu ar trebui să fie apelată cu o valoare NULL. Figura 6 prezintă setul de puncte punctate necesare. Rețineți că a doua punctură specifică punctul punct punct al instanței TwoDShape. Aceasta înseamnă că această punctură selectează în obiectele numai apelurile la metoda distanței.
Figura 6. Punctul (punctele de secțiune) pentru a testa argumentele
În cele din urmă, trebuie să adăugați recomandări relevante (recomandări). Pentru simplificare, obținem un mesaj la detectarea unui argument invalid, și apoi, dacă theconstructor, modificați valorile reale la zero și să ignorați tehnica de apel la distanță atunci când transmite valoarea NULL. Figura 7 prezintă două astfel de elemente de consiliere.
Figura 7. Elementul de consultare a argumentării argumentului
Când încercați să executați următoarea teză:
Cercul c3 = cerc nou (3,0,2,0, -2,0);
în program, primește următorul mesaj:
Cu mesajele de eroare, puteți face mult mai mult dacă specificați numărul liniei exacte și numele fișierului sursă în ele, dar acest exemplu nu servește acestui scop.
În proiectele mari, unde sunt utilizate mai multe clase și se folosesc mai multe interfețe, codul pentru aspectele care implementează verificarea argumentului poate fi organizat într-un director separat. Pot oferi mai multe modalități de a organiza aspecte pentru identificarea și întreținerea lor simplă. Când creați un sistem pentru scopuri interne, puteți utiliza configurația designului intern, atunci când creați sistemul pentru clienți externi - o configurație care include aspecte. Eclipse AJDT vă permite să creați pur și simplu noi configurații de configurație.
Aspecte și modele de design
jan / AODPs / puteți încărca codul care implementează șabloanele de grup GOF.5. 5 Nicholas Lesiecki a scris, de asemenea, despre modelele de design pentru site-ul IBM developerWorks. 6 În articolul său este prezentată o descriere mai completă în comparație cu acest articol.
Luați în considerare un exemplu foarte simplu de implementare a modelului standard al adaptorului în AspectJ.
Figura 8 prezintă diagrama Unified Modeling Language (UML) pentru șablonul Adaptor. În acest șablon clientul cere un serviciu și se creează o interogare pentru aceasta. Este posibil să existe mulți furnizori de servicii și fiecare dintre ei poate avea un nume de serviciu diferit sau unele cerințe nestandardizate care trebuie îndeplinite de partea solicitantă. Un design bun orientat-obiect sugerează că cererea de serviciu este încapsulat în interfața țintă, interfața programului și, dacă este necesar, un adaptor care acționează ca intermediar între client și serviciul (în formă de diagramă Adaptee).
Figura 8. Model adaptor
Abordarea folosind adaptorul pare destul de rezonabilă și eficientă. Dar ce să facem în cazul unui sistem învechit care nu este proiectat să funcționeze cu șabloane sau adaptoare? Dezvoltatorii acestor sisteme nu au realizat posibilitatea unei schimbări viitoare. Apelurile de servicii pot fi împrăștiate în întreaga aplicație. Cum să implementați un nou serviciu îmbunătățit? Fără aspecte, va trebui probabil să restaurați codul sursă al sistemului, să căutați toate apelurile de servicii, să dezvoltați un adaptor și să implementați modelul Adaptor. În funcție de numărul de apeluri către serviciul vechi, aceasta poate fi o sarcină destul de obositoare. Restabilirea codului sursă și îmbunătățirea acestuia este un obiectiv demn, dar nu este întotdeauna posibil să se permită un astfel de lux. Trebuie să fim mulțumiți de alocarea de coduri, acesta este cel mai bun lucru care se poate face într-un timp scurt.
În acest caz, puteți crea o versiune AOP a șablonului Adaptor care rezolvă imediat problema și vă permite să parcurgeți mai departe un sistem mai bine organizat și mai bine proiectat.
Figura 9 prezintă un simplu client care utilizează serviciul. Serviciul returnează distanța de la un punct la obiectul Client curent.
Figura 9. Un client simplu
Interfața pentru serviciu descrie o metodă separată:
Un nou furnizor îmbunătățit de servicii are o metodă cu un nume puțin diferit și alți parametri. Interfața sa:
Trebuie să creăm un adaptor care să fie localizat între apelurile către serviciul vechi, să primească argumentele corespunzătoare pentru noul serviciu, să apeleze noul serviciu și să returneze rezultatele clientului. Clientul nu se schimbă în același timp. Aspectul necesar pentru acest lucru este prezentat în Figura 10.
Figura 10. Aspectul adaptorului pentru apelarea unui nou serviciu
Acordați atenție simplității aspectului. Declarăm un punct punct pentru a identifica fiecare apel la metoda useService a serviciului sursă. Apoi, utilizați sfatul în jur pentru a înlocui acest apel printr-un nou apel de serviciu după preluarea informațiilor necesare de la clientul apelant.
Această abordare are avantajele și dezavantajele sale. În primul rând, utilizând acest aspect simplu, puteți face modificări pe tot codul aplicației. De asemenea, puteți încapsula o relație pentru a apela un serviciu dintr-o locație. Acum, dacă noul serviciu este înlocuit cu unul nou, va trebui să modificați numai codul de aspect. Acesta este un avantaj pentru un sistem mai fiabil.
Principalul dezavantaj este că clientul vechi rămâne în sistem, chiar dacă acesta nu este utilizat. Dacă există timp (care, se pare, nu există niciodată), este foarte probabil că va trebui să reveniți și să restaurați codul sursă al sistemului pentru a utiliza șablonul Adaptor standard. Cel mai mic, puteți modifica metoda useService a serviciului sursă la codul care returnează o valoare ingenioasă, de exemplu, 0.0, deoarece această metodă nu va fi apelată niciodată.
Aplicarea la nivel profesional
Până în prezent, au fost luate în considerare exemple în mod clar limitate, dar încă utile ale aplicării AOP. Se pune întrebarea, dar cât de bine această metodă este redusă. Voi sublinia și descrie pe scurt un exemplu binecunoscut. O examinare mai detaliată va necesita scrierea unui alt articol.
Poate că unii dintre voi sunteți familiarizați cu Cadrul de primăvară, 7 reprezentând o infrastructură de aplicații care susține dezvoltarea de aplicații pentru întreprinderi. Framework-ul de primăvară oferă un mediu J2EE multi-nivel pentru construirea de aplicații complexe pentru întreprinderi. AOP este una dintre principalele tehnologii utilizate în primăvară. Comunitatea de primăvară și-a dezvoltat propria implementare orientată spre aspect, ceea ce permite logica complexă să fie aplicată codului la timpul de execuție, mai degrabă decât la timpul de compilare, ca în AspectJ. Dar există funcții de integrare care vă permit să includeți ușor AspectJ în Cadrul de primăvară.
În prezent, primăvara este folosită într-o varietate de organizații pentru a crea aplicații de întreprindere care sunt mai bine proiectate și necesită mai puțin timp de dezvoltare. Potrivit estimărilor mele, acesta este un excelent exemplu de aplicare a aspectelor la problemele reale. 8
Ce pot face în continuare?
În opinia mea, în viitor, AOP va deveni parte a setului de instrumente software pentru dezvoltatori. Nu știu dacă vom ajunge la punctul în care vom crea un sistem folosind AOP ca mecanism principal pentru proiectarea, dar cred că vom găsi modalități de a îmbunătăți aspecte ale utilizării proiectelor orientate obiect existent. Mai multe lucruri pot accelera procesul.
În primul rând, sunt necesare implementări standard AOP stabile. Acest proces a început deja. Versiunea 5 AspectJ combină cele două limbi cele mai populare ale AOP Java - AspectJ și AspectWerkz. Implementările standard în alte limbi, cum ar fi C ++, ajută de asemenea.
În al doilea rând, este necesar să se dezvolte metrici care să ne permită să justificăm eficacitatea aplicării AOP la sistemele individuale. De exemplu, re-implementarea modelelor de design folosind AOP va fi mai bună decât șabloanele standard orientate pe obiecte? În ce cazuri sunt șabloanele mai bune și în ce - nu? Ce metrici sunt necesare pentru a obține informații despre cum să dezvoltați aceste valori? Momentul unei abordări simple, atunci când sistemul proiectat de obiecte (sau orice alt sistem ales de dvs.) a fost considerat bun (), a trecut. Este necesar să se creeze un proiect și soluții de implementare bazate pe date empirice. 9
În al treilea rând, este necesar să se continue dezvoltarea instrumentelor care să sprijine AOP. Sunt fericit să vă anunț că noul AJDT pentru Eclipse este un set minunat de instrumente. Aceste instrumente au îmbunătățit sprijinul necesar pentru utilizarea efectivă și rațională a aspectelor. Instrumentele ar trebui să sprijine, de asemenea, noile tehnologii care utilizează aspecte.
Aspecte ar trebui să fie menținute. Acestea nu au devenit încă parte din principalele aplicații, dar se apropie de ea în fiecare zi. Vă recomandăm să vă familiarizați cu aspectele și să le studiați cu atenție.
notițe
GOF Grupul 3 - Erich Gamma (Erich Gamma), Richard Helm (Richard Helm), Ralph Johnson (Ralph Johnson) și John Vlissides (Ioan Vlissides), a scris cartea Design Patterns. Aceasta este o carte fundamentală privind modelele de design;
7 Dacă cititorii care utilizează AOP doresc să-și împărtășească experiențele și să furnizeze date pentru cercetarea mea privind valorile AOP, vă rugăm să mă contactați.