Aspect Oriented Programming

La tecnica (AOP), che vado ad illustrare, è nata nel mondo Java, grazie al contributo del solito geniaccio della Xerox (ma non facevano fotocopiatrici?). Con un aspect possiamo andare ad influenzare codice già scritto attraverso dei Join Points. Banalmente potremmo utilizzare questa tecnica per fare il logging del nostro codice senza influenzare minimamente il codice già scritto. Nella pratica potremmo estendere del tutto il funzionamento di una classe completamente dall’esterno (dipende da come è scritto il codice ovviamente). Siccome per lavoro sono costretto ad usare Visual Studio .Net, mi sono preoccupato di reperire qualcosa che consenta di utilizzare l’AOP con C# & Co. Quello che in Java è uno standard da tempo per il .Net ha richiesto la smobilitazione del Microsoft Research Center, la riscrittura del compilatore e via di questo passo (sorte noscia). Fortunatamente un professore russo ha messo insieme il tutto in un comodo pacco zip che è possibile reperire qui (per il funzionamento richiede il Phoenix RDK).
Vediamo dunque in cosa consiste questo AOP con un esempio piccolo piccolo (i concetti si applicano in Java alla stessa maniera). Supponiamo di avere una console application col seguente codice:

using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void P()
        { Console.WriteLine("P"); }

        static void Main(string[] args)
        {
            Console.WriteLine("Main");
            P();
        }
    }
}

Si tratta quindi di una chiamata al metodo P. Adesso vogliamo estendere la classe in modo che, quando viene effettuata una qualsiasi chiamata, sia prima che dopo, io possa compiere qualche azione, ad esempio stampare un messaggio di log. Aspect.Net permette di definire ciò con un apposito linguaggio che viene successivamente convertito in C#. Aggiungiamo quindi alla nostra soluzione un progetto di tipo Aspect ML, scritto così:

%aspect Aspect2

using System;
using AspectDotNet;

{
   %modules
      public static void Say (String s)
      { Console.WriteLine(s); }

   %rules
      % before % call *
      % action
      public static void SayHello ()
      { Say ("Hello " + %TargetMemberInfo.Name); }

      % after % call *
      % action
      public static void SayBye ()
      { Say ("Bye " + %TargetMemberInfo.Name); }
}

in cui indichiamo che prima di fare qualsiasi chiamata (%before %call *) dobbiamo eseguire la action SayHello(); subito dopo la chiamata (%after %call *), invece, dobbiamo eseguire la action SayBye(). Se già vi state meravigliando di tutto ciò, sappiate che gli Aspect Oriented Languages effettuano quello che è chiamato Mixing del codice: il compilatore si occupa di scovare quali sono i punti in cui il nostro aspect si può inserire (e questo viene fatto direttamente sugli assembly) e ci crea una versione AOP della nostra console application il cui output sarà:

Hello Void WriteLine(System.String)
Main
Bye Void WriteLine(System.String)
Hello Void P()
Hello Void WriteLine(System.String)
P
Bye Void WriteLine(System.String)
Bye Void P()

Bello vero?
A presto con qualche esempio più complesso ma a voi l’immaginazione di cosa poter fare con uno strumento simile.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *