Alcuni problemi sono risolti in modo più elegante con AOP?

18

Mi sono imbattuto nell'idea di Aspect Oriented Programming e ho alcune preoccupazioni in merito.

L'idea di base sembra essere quella di voler prendere preoccupazioni trasversali che non sono ben modularizzate usando l'oggetto e modularizzandole. Questo è tutto molto bene e bene.

Ma l'implementazione di AOP sembra essere quella di modificare il codice dall'esterno del modulo. Quindi, ad esempio, è possibile scrivere un aspetto che cambia ciò che accade quando un particolare oggetto viene passato come parametro in una funzione. Questo sembra andare direttamente contro l'idea dei moduli. Non dovrei essere in grado di modificare il comportamento di un modulo al di fuori di quel modulo, altrimenti l'intero punto dei moduli viene rovesciato. Ma gli aspetti sembrano fare esattamente questo!

Fondamentalmente, gli aspetti sembrano essere una forma di patch di codice. Potrebbe essere utile per alcuni hack veloci; ma, come principio generale, forse non è qualcosa che vuoi fare. La programmazione orientata all'aspetto mi sembra una cattiva pratica e un principio di progettazione generale.

L'AOP è una buona pratica? Alcuni problemi di programmazione sono risolti in modo più elegante con AOP?

    
posta Winston Ewert 16.11.2010 - 04:43
fonte

3 risposte

18

La programmazione orientata agli aspetti consente di eseguire determinati tipi di programmazione che sono difficili da fare senza codice inutilmente diffuso in tutta l'applicazione o nella libreria che non è correlato alle funzioni principali del software (vale a dire preoccupazioni trasversali). Gli esempi includono:

  1. Registrazione e monitoraggio
  2. Analisi delle prestazioni
  3. Debugging and Tracing
  4. Annulla funzionalità
  5. Convalida di input e output
  6. Morphing del comportamento degli oggetti esistenti
  7. Filtri oggetto
  8. Implementazione della sicurezza
  9. Gestione delle transazioni

Limitando tali preoccupazioni trasversali a una singola parte dell'applicazione, e quindi facendo riferimento a queste caratteristiche nel codice tramite attributi, intercettazione di chiamata di metodo o proxy dinamici, si consente l'incapsulamento del comportamento trasversale; questo ha tutti i vantaggi (vale a dire un singolo punto di modifica) che l'incapsulamento potrebbe fornire in qualsiasi altro punto della tua applicazione.

Il punto chiave qui è che AOP incapsula un comportamento che è 1) comune in tutta l'applicazione, e 2) periferico alla funzionalità primaria dell'applicazione.

    
risposta data 16.11.2010 - 06:08
fonte
6

Venendo in ritardo al gioco, ma fornisco questo per gli sviluppatori successivi che potrebbero imbattersi in questa domanda.

Vorrei strongmente sconsigliare AOP se l'applicazione dipende su di esso per funzionare correttamente. Gli aspetti funzionano così:

  • Consigli (comportamento aggiuntivo) viene applicato a
  • Punti di unione (luoghi in cui è possibile collegare il codice aggiuntivo, ovvero iniziare o terminare un metodo o quando si attiva un determinato evento)
  • ... dove i pattern pointcut (un pattern che rileva se un dato punto di join corrisponde)

Per chiunque abbia fatto computer da molto tempo, il fatto che i pattern siano usati potrebbe essere qualcosa da guardare da vicino. Quindi, ecco un esempio di un collegamento che corrisponde a qualsiasi metodo denominato set indipendentemente dagli argomenti:

call(* set(..))

Quindi questo è un punto di discussione abbastanza ampio e dovrebbe essere chiaro che maneggiarlo con cura è consigliato (non è un gioco di parole) perché stai chiedendo consigli a molte cose.

O diamine, applichiamo i consigli a tutto , indipendentemente dal nome o dalla firma!

execution(* *(..))

Quindi dovremmo stare attenti perché qui c'è molto potere, ma questo non è un argomento contro gli aspetti - è un argomento di cautela perché qui c'è molto potere e la corrispondenza dei modelli può facilmente andare storto (basta premere il tuo preferito motore di ricerca per cimici e divertiti).

Quindi ecco quello che sembra un pointcut relativamente sicuro:

pointcut setter(): target(Point) &&
                   ( call(void setX(int)) ||
                     call(void setY(int)) );

Che fornisce esplicitamente un consiglio se vengono trovati metodi denominati setX o setY su un oggetto Point . I metodi possono ricevere solo int s e devono essere void . Sembra abbastanza sicuro, giusto? Bene, questo è sicuro se quei metodi esistono e hai applicato il consiglio corretto. Se no, peccato; fallisce silenziosamente.

Per fare un esempio, un amico stava provando a eseguire il debug di un'applicazione Java in cui tutti, una volta ogni tanto, avrebbero restituito dati non corretti. Si è trattato di un errore raro e non sembra essere correlato a particolari eventi o dati in particolare. Era un bug di threading, qualcosa che è notoriamente difficile da testare o rilevare. A quanto pare, stavano usando aspetti per bloccare i metodi e renderli "thread safe", ma un programmatore ha rinominato un metodo e un pointcut non è riuscito a farlo corrispondere, causando così una rottura silenziosa dell'applicazione.

Quindi, dico alle persone che se devono utilizzare AOP, per trattare aspetti come le eccezioni: in un sistema ben progettato e se nulla va storto, possono essere rimossi e il software funziona ancora correttamente . Tuttavia, se la funzionalità del programma dipende da AOP, si introduce una fragilità nel programma che non è giustificata.

Quindi, logging, debugging e tracing sono ottimi esempi di comportamenti perfetti per gli aspetti, ma sicurezza? No. Filo di sicurezza? No..

Per una valida alternativa all'AOP, vedi tratti . Piuttosto che essere imbullonati al linguaggio, sono integrati direttamente in esso, non hanno bisogno di un IDE "tratto consapevole" (sebbene possa essere d'aiuto) e hanno fallimenti in fase di compilazione se i metodi richiesti non sono presenti. I tratti svolgono un lavoro molto più accurato nel gestire la separazione delle preoccupazioni perché il problema è stato definito meglio sin dall'inizio. Li uso estensivamente e sono fantastici.

    
risposta data 17.08.2013 - 09:18
fonte
2

Una situazione in cui AOP potrebbe essere l'unica soluzione decente e pratica è quando non si ha accesso al codice sorgente . Per utilizzare il vecchio esempio stanco della preoccupazione trasversale di Logging:

Diciamo che vuoi registrare il flusso del controllo in una libreria di terze parti che consumi. Hai il tuo codice completamente strumentato con le dichiarazioni di registrazione. Tuttavia, per questa libreria non hai la fonte, rendendo impossibile aggiungere le tue dichiarazioni di registrazione. Dato che fai ha il bytecode, AOP ti consente comunque di strumentare quella libreria di terze parti.

E se stai creando comunque un aspetto di Logging, potresti anche considerare l'implementazione della registrazione con AOP attraverso il tuo codice.

    
risposta data 16.11.2010 - 05:58
fonte

Leggi altre domande sui tag