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


19

Mi sono imbattuto nell'idea della programmazione orientata agli aspetti e ne ho alcune preoccupazioni.

L'idea di base sembra essere che vogliamo prendere preoccupazioni trasversali che non sono ben modularizzate usando l'oggetto e modulare. Va tutto bene e bene.

Ma l'implementazione di AOP sembra essere quella di modificare il codice dall'esterno del modulo. Quindi, ad esempio, potrebbe essere scritto un aspetto che modifica ciò che accade quando un determinato 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 dall'esterno di quel modulo, altrimenti l'intero punto dei moduli viene capovolto. Ma gli aspetti sembrano fare esattamente questo!

Fondamentalmente, gli aspetti sembrano essere una forma di patch di codice. Può essere utile per alcuni hack rapidi; ma, come principio generale, forse non è qualcosa che vuoi fare. La programmazione orientata agli aspetti mi sembra prendere una cattiva pratica e elevarsi a un principio di progettazione generale.

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


ahhh, la famosa patch di scimmia!
Muad'Dib,

1
Ho modificato la domanda per migliorarne il tono e ho votato per riaprire.
Robert Harvey,

Questio è stato anche richiesto nuovamente in una forma diversa qui: programmers.stackexchange.com/questions/19344/…
Peter Boughton

Risposte:


19

La programmazione orientata agli aspetti rende possibile eseguire determinati tipi di programmazione che sono difficili da fare senza spargere inutilmente il codice in tutta l'applicazione o la libreria che non è correlato alle funzioni primarie del software (ovvero problemi trasversali). Esempi inclusi:

  1. Registrazione e monitoraggio
  2. Analisi di performance
  3. Debug e traccia
  4. Annulla funzionalità
  5. Convalida di ingressi e uscite
  6. Morphing del comportamento di oggetti esistenti
  7. Filtri oggetto
  8. Implementazione della sicurezza
  9. Gestire le transazioni

Limitando tali preoccupazioni trasversali a una singola parte dell'applicazione e facendo quindi riferimento a queste funzionalità nel codice tramite attributi, intercettazione di chiamate di metodo o proxy dinamici, si consente l'incapsulamento del comportamento trasversale; questo ha tutti i vantaggi (cioè un singolo punto di modifica) che l'incapsulamento fornirebbe in qualsiasi altra parte dell'applicazione.

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


7

Arrivo in ritardo al gioco, ma lo fornisco agli sviluppatori successivi che potrebbero imbattersi in questa domanda.

Consiglio vivamente contro AOP se la sua applicazione dipende da essa per funzionare correttamente. Gli aspetti funzionano così:

  • Viene applicato un consiglio (comportamento aggiuntivo)
  • Unisci punti (luoghi in cui è possibile allegare il codice aggiuntivo, ad esempio l'inizio o la fine di un metodo o quando si attiva un determinato evento)
  • ... dove corrispondono i pattern pointcut (un pattern che rileva se un dato punto di join corrisponde)

Per chiunque stia facendo computer da molto tempo, il fatto che i modelli vengano utilizzati potrebbe essere qualcosa da guardare da vicino. Quindi, ecco un esempio di un punto di corrispondenza che corrisponde a qualsiasi metodo denominato setindipendentemente dagli argomenti:

call(* set(..))

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

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

execution(* *(..))

Quindi chiaramente dovremmo stare attenti perché c'è molto potere qui, ma questo non è un argomento contro gli aspetti - è un argomento di cautela perché c'è molto potere qui e la corrispondenza dei modelli può facilmente andare storta (basta colpire il tuo motore di ricerca preferito per aop bugs e buon divertimento).

Quindi ecco quello che sembra un punto relativamente sicuro:

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

Ciò fornisce esplicitamente consigli se vengono trovati metodi denominati setXo setYsu un Pointoggetto. I metodi possono solo ricevere intse devono essere void. Sembra abbastanza sicuro, giusto? Bene, è sicuro se esistono questi metodi e hai applicato il consiglio corretto. Altrimenti, peccato; fallisce silenziosamente.

Per fare un esempio, un amico stava cercando di eseguire il debug di un'applicazione Java in cui tutti di tanto in tanto restituivano dati errati. Si è trattato di un fallimento raro e non sembrava essere correlato a eventi o dati particolari 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 ribattezzato un metodo e un taglio di punti non è riuscito a combaciarlo, causando così un'interruzione silenziosa dell'applicazione.

Pertanto, dico alla gente che se devono usare 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 nel programma una fragilità ingiustificata.

Pertanto, la registrazione, il debug e la traccia sono ottimi esempi di comportamenti che sono perfetti per gli aspetti, ma la sicurezza? No. Sicurezza del filo? No.

Per una valida alternativa a AOP, vedi tratti . Invece di essere collegati al linguaggio, sono integrati direttamente in esso, non hanno bisogno di un IDE "consapevole del tratto" (anche se può aiutare) e hanno errori in fase di compilazione se i metodi richiesti non sono presenti. I tratti svolgono un lavoro molto più pulito nel gestire la separazione delle preoccupazioni perché il problema è stato meglio definito dall'inizio. Li uso ampiamente e sono fantastici.


Piuttosto che sostenere che AOP non dovrebbe essere usato per la funzionalità di base, potrebbe essere più appropriato dire che i tagli di punti che si basano sui nomi dei metodi sono una cattiva idea. Probabilmente direi che anche il blocco e la sincronizzazione non sono buoni casi d'uso per AOP.
Codice Bling

2

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

Supponiamo che tu voglia registrare il flusso di controllo in una libreria di terze parti che consumi. Hai il tuo codice completamente dotato di istruzioni di registrazione. Tuttavia, per questa libreria non hai l'origine, rendendo impossibile aggiungere le tue dichiarazioni di registrazione. Dal momento che fare avere il bytecode, AOP consente di strumento di terze parti biblioteca in ogni caso.

E se stai comunque creando un aspetto di registrazione, potresti anche considerare di implementare la registrazione con AOP attraverso il tuo codice.


La registrazione è per cose "interessanti". Come si possono fare altre cose oltre a "entrare con questi parametri" e "uscire" con la registrazione AOP?

@Thorbjorn: registrazione / debug / tracciamento è solo una delle molte aree di funzionalità che AOP può aiutare. L'ho usato come esempio per illustrare il mio punto. Il punto che sto cercando di sottolineare è che AOP ti offre un maggiore controllo sul bytecode di terze parti.
Joseph Tanenbaum,

certo, ma volevo davvero sapere se la registrazione AOP può fare di più oltre alla registrazione enter-exit?

Dipende dallo strumento AOP che usi, ma ci sono sicuramente dei limiti a ciò che puoi fare. Potrebbe benissimo essere impossibile andare oltre la registrazione enter-exit.
Joseph Tanenbaum,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.