Programmazione orientata agli aspetti rispetto alla programmazione orientata agli oggetti

Come molti sviluppatori qui e in tutto il mondo, ho sviluppato per molti anni sistemi software che utilizzano tecniche di programmazione orientata agli oggetti (OOP). Quindi, quando leggo che la programmazione orientata agli aspetti (AOP) risolve molti dei problemi che l’OOP tradizionale non risolve completamente o direttamente, metto in pausa e penso, è reale?

Ho letto molte informazioni cercando di imparare le chiavi di questo paradigma AOP e sono nello stesso posto, quindi volevo capire meglio i suoi benefici nello sviluppo di applicazioni nel mondo reale.

Qualcuno ha la risposta?

Perché “vs”? Non è “vs”. È ansible utilizzare la programmazione orientata all’aspetto in combinazione con la programmazione funzionale, ma anche in combinazione con quella orientata agli oggetti. Non è “vs”, è “Aspect Oriented Programming with Object Oriented Programming”.

Per me AOP è una sorta di “meta-programmazione”. Tutto ciò che fa AOP può essere fatto anche senza aggiungere altro codice. AOP ti limita a scrivere questo codice.

Wikipedia ha uno dei migliori esempi per questa meta-programmazione. Supponi di avere una class grafica con molti metodi “set … ()”. Dopo ogni metodo impostato, i dati della grafica sono cambiati, quindi la grafica è cambiata e quindi la grafica deve essere aggiornata sullo schermo. Si supponga di ridipingere la grafica che è necessario chiamare “Display.update ()”. L’approccio classico è di risolvere questo aggiungendo altro codice . Alla fine di ogni metodo impostato scrivi

void set...(...) { : : Display.update(); } 

Se hai 3 metodi di set, non è un problema. Se ne hai 200 (ipotetici), è davvero doloroso aggiungerlo ovunque. Inoltre, ogni volta che aggiungi un nuovo metodo set, devi essere sicuro di non dimenticare di aggiungerlo alla fine, altrimenti hai appena creato un bug.

AOP risolve questo senza aggiungere tonnellate di codice, invece si aggiunge un aspetto:

 after() : set() { Display.update(); } 

E questo è tutto! Invece di scrivere il codice di aggiornamento da soli, devi solo dire al sistema che dopo aver raggiunto un punto () pointcut, deve eseguire questo codice e verrà eseguito questo codice. Non è necessario aggiornare 200 metodi, non è necessario assicurarsi di non dimenticare di aggiungere questo codice su un nuovo metodo set. Inoltre hai solo bisogno di un collegamento:

 pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*); 

Cosa significa? Ciò significa che se un metodo è denominato “set *” (* significa che qualsiasi nome potrebbe seguire dopo l’impostazione), indipendentemente da ciò che il metodo restituisce (primo asterisco) o quali parametri richiede (terzo asterisco) ed è un metodo di MyGraphicsClass e questo class fa parte del pacchetto “com.company. *”, quindi questo è un set () pointcut. E il nostro primo codice dice ” dopo aver eseguito qualsiasi metodo che sia un set pointcut, esegui il seguente codice”.

Guarda come AOP risolve elegantemente il problema qui? In realtà tutto quanto descritto qui può essere fatto in fase di compilazione. Un preprocessore AOP può semplicemente modificare la sorgente (ad esempio aggiungendo Display.update () alla fine di ogni metodo set-pointcut) prima ancora di compilare la class stessa.

Tuttavia, questo esempio mostra anche uno dei grandi lati negativi di AOP. AOP sta effettivamente facendo qualcosa che molti programmatori considerano un ” Anti-Pattern “. Il modello esatto è chiamato ” Azione a distanza “.

L’azione a distanza è un anti-modello (un errore comune riconosciuto) in cui il comportamento in una parte di un programma varia selvaggiamente sulla base di operazioni difficili o impossibili da identificare in un’altra parte del programma.

Come novizio di un progetto, potrei semplicemente leggere il codice di qualsiasi metodo impostato e considerarlo rotto, in quanto sembra non aggiornare il display. Non vedo guardando solo il codice di un metodo set, che dopo che è stato eseguito, un altro codice verrà “magicamente” eseguito per aggiornare il display. Considero questo un grave svantaggio! Modificando un metodo, potrebbero essere introdotti strani bug. Comprendere ulteriormente il stream di codice del codice in cui certe cose sembrano funzionare correttamente, ma non sono ovvie (come ho detto, funzionano solo magicamente … in qualche modo), è davvero difficile.

Aggiornare

Giusto per chiarire che: alcune persone potrebbero avere l’impressione che sto dicendo che AOP è qualcosa di brutto e non dovrebbe essere usato. Non è quello che sto dicendo! AOP è in realtà una grande funzionalità. Dico solo “Usalo attentamente”. AOP causerà solo problemi se si mischiano il normale codice e AOP per lo stesso Aspetto . Nell’esempio sopra, abbiamo l’Aspetto di aggiornare i valori di un object grafico e dipingere l’object aggiornato. Questo è in realtà un singolo aspetto. Codificarne metà come codice normale e l’altra metà come aspetto è ciò che aggiunge il problema.

Se si utilizza AOP per un aspetto completamente diverso, ad esempio per la registrazione, non si verificherà il problema di anti-pattern. In tal caso, un principiante del progetto potrebbe chiedersi “Da dove vengono tutti questi messaggi di registro? Non vedo alcun output di registro nel codice”, ma non è un grosso problema. Le modifiche apportate alla logica del programma difficilmente interromperanno la struttura del registro e le modifiche apportate alla struttura del registro difficilmente interromperanno la logica del programma: questi aspetti sono completamente separati. L’utilizzo di AOP per la registrazione ha il vantaggio che il codice del programma può concentrarsi completamente nel fare tutto ciò che dovrebbe fare e si può comunque avere una registrazione sofisticata, senza che il codice venga ingombrato da centinaia di messaggi di registro ovunque. Anche quando viene introdotto un nuovo codice, magicamente i messaggi di log appariranno al momento giusto con il contenuto giusto. Il programmatore novizio potrebbe non capire perché sono lì o da dove sono venuti, ma dal momento che registreranno la “cosa giusta” al “momento giusto”, può semplicemente accettare felicemente il fatto che siano lì e passare a qualcos’altro .

Quindi un buon utilizzo di AOP nel mio esempio potrebbe essere quello di registrare sempre se qualche valore è stato aggiornato tramite un metodo set. Ciò non creerà un anti-modello e difficilmente sarà la causa di alcun problema.

Si potrebbe dire, se si può facilmente abusare di AOP per creare così tanti problemi, è una ctriggers idea usare tutto. Tuttavia quale tecnologia non può essere abusata? È ansible abusare di dati incapsulati, è ansible abusare dell’ereditarietà. Praticamente tutte le utili tecnologie di programmazione possono essere sfruttate. Considera un linguaggio di programmazione così limitato che contiene solo funzioni che non possono essere abusate; una lingua in cui le funzioni possono essere utilizzate solo perché inizialmente erano destinate a essere utilizzate. Un tale linguaggio sarebbe così limitato che è discutibile se può essere persino usato per la programmazione del mondo reale.

OOP e AOP non si escludono a vicenda. AOP può essere una buona aggiunta a OOP. AOP è particolarmente utile per aggiungere codice standard come registrazione, tracciamento delle prestazioni, ecc. A metodi senza intasare il codice del metodo con questo codice standard.

la programmazione orientata all’aspetto fornisce un buon modo per implementare preoccupazioni trasversali come la registrazione e la sicurezza. Questi conceti trasversali sono pezzi di logica che devono essere applicati in molti luoghi ma in realtà non hanno nulla a che fare con la logica aziendale.

Non si dovrebbe vedere AOP come una sostituzione di OOP, più come un bel componente aggiuntivo, che rende il codice più pulito, liberamente accoppiato e focalizzato sulla logica di business. Quindi applicando AOP otterrai 2 importanti vantaggi:

  1. La logica di ogni preoccupazione è ora in un posto, a differenza di essere sparsi su tutto il codice di base.

  2. le classi sono più pulite poiché contengono solo il codice per la loro preoccupazione principale (o funzionalità di base) e le preoccupazioni secondarie sono state spostate su aspetti.

Penso che non ci sia una risposta generale a questa domanda, ma una cosa da notare è che AOP non sostituisce l’ OOP, ma aggiunge alcune caratteristiche di decomposizione che affrontano la cosiddetta tirannia della composizione dominante ( 1 ) (o preoccupazioni trasversali).

In determinati casi, è sicuramente utile purché tu abbia il controllo degli strumenti e dei linguaggi da utilizzare per un progetto specifico, ma aggiunga anche un nuovo livello di complessità per quanto riguarda l’interazione degli aspetti e la necessità di strumenti aggiuntivi come l’ AJDT per capire ancora il tuo programma

Gregor Kiczales ha tenuto una volta un interessante discorso introduttivo su AOP a Google Tech Talks, che consiglio di osservare: Aspect Oriented Programming: Radical Research in Modularity .

Prima di tutto AOP non sostituirà OOP. AOP estende OOP. Le idee e le pratiche di OOP rimangono pertinenti. Avere un buon design degli oggetti probabilmente renderà più facile estenderlo con aspetti.

Penso che le idee che l’AOP apporta siano importanti. Abbiamo bisogno di elaborare modi per implementare le preoccupazioni trasversali su diverse classi del tuo programma senza dover cambiare le classi stesse. Ma penso che l’AOP alla fine diventerà solo parte di altri strumenti che usiamo e non uno strumento o una tecnica separata. Lo vediamo già succedere.

Un paio di linguaggi dinamici come Ruby e Python hanno costrutti linguistici come mixin che risolvono gli stessi problemi. Questo assomiglia molto ad AOP ma è meglio integrato nella lingua.

Spring e Castle e un paio di altre strutture di iniezione delle dipendenze hanno opzioni per aggiungere un comportamento alle classi che iniettano. Questo è un modo di fare tessere a runtime e penso che questo abbia un grande potenziale.

Non penso che dovrai imparare un paradigma completamente nuovo per usare AOP. Le idee sono interessanti ma vengono assorbite lentamente dagli strumenti e dai linguaggi esistenti. Tieniti informato e prova questi strumenti.

AOP è un nuovo paradigma di programmazione che si occupa di questo concetto. Un aspetto è un’ quadro software che implementa una parte non funzionale specifica dell’applicazione.

Penso che questo articolo sia un buon punto di partenza per Aspect Oriented Programming: http://www.jaftalks.com/wp/index.php/introduction-to-aspect-oriented-programming/