Quali alternative ci sono per preoccupazioni trasversali oltre alla programmazione orientata all'aspetto? [chiuso]


19

La programmazione orientata agli aspetti promette di affrontare questioni trasversali, ma non sono ancora completamente venduta. Ci sono stati altri tentativi di affrontare questo problema?


Il modello di visitatore può affrontare molte situazioni che sono ora risolte tramite AOP.
Steven Evers,

@SnOrfus: vedi anche la mia risposta di seguito, dove parlo della libreria DJ per Java: un modo dinamico di usare il modello visitatore! Vale la pena dare un'occhiata. (È anche una tecnica generale che puoi usare da solo con Reflection.)
Macneil

Risposte:


7

Se possibile, è possibile incapsulare le preoccupazioni trasversali in moduli separati che vengono quindi utilizzati in tutta l'app tramite l'iniezione delle dipendenze. Ciò consente di disaccoppiare in qualche modo l'implementazione trasversale delle preoccupazioni dal suo utilizzo in tutto il codice.

Tuttavia, non sempre funziona in modo elegante. Questo è il motivo per cui le persone stanno cercando di affrontare il problema con cose come AOP.


6

Altre due opzioni che non ho ancora visto esplorate:

Programmazione funzionale con monadi e frecce

In FP rappresenti una preoccupazione trasversale come qualsiasi altra cosa: come qualcosa che passi in una chiamata di funzione. Dato che farlo diventa esplicitamente noioso, puoi usare Monads (o forse le frecce) per nascondere le informazioni extra che vengono trasmesse.

L'esempio AOP più comune è la registrazione. Con Monads, creeresti una monade "Logger" che conserva un elenco di messaggi. Qualsiasi funzione eseguita tramite LoggerMonad ha la possibilità di pubblicare un messaggio di registro. Con le frecce, modelleresti l'intero flusso di dati dell'applicazione e, se del caso, lavoreresti nel modello di una registrazione. Penso. Le frecce sono piuttosto complesse.

Programmazione basata su entità / componenti

Qualcosa che ho cercato e sperimentato per un motore di gioco. Invece di "oggetti" come in OOP, si decompone tutto in pacchetti di dati (componenti) e servizi che operano su un tipo di componente. I componenti sono raggruppati in base a ID comuni, come in un database relazionale, e i gruppi di componenti collegati sono le Entità. Per aggiungere la registrazione in tale sistema, aggiungere un nuovo servizio di registrazione i trigger in base ai componenti che lo attraversano.

Entrambi i metodi consentono di lavorare facilmente un cambiamento trasversale molto facilmente, ma entrambi sono modelli architettonici di alto livello. Quindi probabilmente dovresti usarli dall'inizio. In teoria, il modello Component può essere elaborato in un sistema OOP esistente. Immagino che anche le monadi potrebbero esserlo se la tua lingua è abbastanza potente.


Quando parli di Monadi e Frecce, dovresti anche menzionare i Funzionari Applicativi.
Waquo

3

Esistono diversi modi per affrontare i problemi delle preoccupazioni trasversali:

  • Usa modelli di progettazione, modi di dire o meccanismi di astrazione migliori : il codice può essere incrociato anche se può essere modulare. Al fine di mantenere il codice, è necessario refactoring per utilizzare la tecnica di progettazione in grado di modularizzarlo. Tale refactoring può introdurre un taglio trasversale di tipo diverso, ma si spera che i tagli incrociati siano stabili e che non possano cambiare.

  • Sviluppa funzionalità linguistiche più ricche : molte manifestazioni del taglio incrociato possono essere risolte attraverso meccanismi di astrazione migliori e talvolta sono necessarie nuove funzionalità linguistiche. Ad esempio, linguaggi più avanzati che includono funzionalità funzionali e orientate agli oggetti spesso non impiegano altrettanti modelli di progettazione, perché non sono necessari. Si noti che gli stessi modelli di progettazione possono essere trasversali in natura , poiché descrivono i ruoli di diversi oggetti e classi. In Java, la riflessione può spesso essere utilizzata al posto di un aspetto, sebbene a costi di runtime più elevati. Ad esempio, usando reflection, è possibile supportare il modello visitatore su centinaia di classi con solo un paio di righe di codice. La libreria DJdal nordest è una soluzione riflessiva che fa proprio questo. I mixin sono una potente tecnica disponibile in C ++ (ma non Java) e possono darti alcuni degli stessi casi d'uso di un aspetto.

  • Fornire un migliore supporto agli strumenti : tecniche come l'uso grepe l'esecuzione di operazioni di refactoring possono gestire i problemi relativi al codice di taglio incrociato. Ad esempio, il nome di un metodo dichiarato in un'interfaccia può attraversare il programma. (Nota la differenza tecnica qui: è il nome del metodo, non l'implementazione del metodo, che taglia i tagli incrociati). Di solito questo non è un problema in un IDE come Eclipse, dove puoi usare il "rinominare refactoring" per cambiare tutto i luoghi nel tuo codice che usano il nome. In questo modo, è possibile che non siano necessarie funzionalità linguistiche quando l'ambiente di programmazione è abbastanza espressivo per te.

  • Usa linguaggi specifici del dominio : i primi aspetti linguistici, che precedevano AspectJ, erano specifici del dominio e applicati solo a determinati problemi, come la sincronizzazione dei thread o l'analisi del flusso di dati per combinare in modo efficiente composizioni di funzioni. Questi linguaggi erano sperimentali, ma sembravano avere un grande successo nel modulare le preoccupazioni che altrimenti sarebbero state trasversali.

  • Usa tecniche di programmazione generativa : il passaggio al livello meta potrebbe essere considerato una tecnica di implementazione per la programmazione orientata all'aspetto, ma è un'area abbastanza grande da trascendere aspetti semplici. Le tecniche generative (in cui un programma genera codice sorgente per un altro programma) sono anche correlate a linguaggi specifici del dominio.

Per tutti questi, penso che studiare AOP sia appropriato. AOP può aiutarti ad espandere le tue concezioni di codice, anche se non usi un linguaggio AOP.


2

In generale taggare elementi di codice con una funzione dichiarativa, ma in particolare il sistema di attributi nel mondo C # /. NET / Mono.


Può essere più preciso? Quello che descrivi è come funzionano alcuni sistemi AOP.
Steven Evers,

2
È praticamente AOP.
Matt H,

AOP nel suo senso tipico / classico richiede uno strumento di supporto (un aspetto IDE di tessitura) per farlo su larga scala. AOP rende più difficile ragionare sul codice dal solo codice sorgente primario. È più difficile prevedere il comportamento dei componenti quando il programma è infiltrato da aspetti zombi. Attributi o tag forniscono funzionalità simili ma con rappresentazione esplicita nel codice sorgente.

Nota che il mio problema non è esattamente con i problemi risolti dal modo AOP. La mia unica preoccupazione è che con AOP, il mio codice sorgente non è una fonte sufficiente per prevedere il comportamento del mio programma.

@mumtaz: vedo come sarebbe il caso applicando aspetti a un intero spazio dei nomi. L'altro metodo di AOP: attribuire metodi / proprietà / ecc. applicare gli aspetti ad esso, è identico a quello che descrivi.
Steven Evers,

2

Non sono un esperto di AOP, ma dalla sua lettura nel corso degli anni, è sempre sembrata una forma più debole della metaprogrammazione offerta da Lisp , in particolare parti come il suo protocollo metaobject.

Ciò non dovrebbe sorprendere, suppongo: Gregor Kiczales fu uno degli autori di AMOP, e in seguito scrisse AspectJ per Java!

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.