Il modello di progettazione Decorator è un eccellente punto di partenza per implementare preoccupazioni trasversali.
Per prima cosa è necessario definire un'interfaccia che modella il servizio in questione. Quindi implementate la reale funzionalità di quel servizio senza pensare alla vostra preoccupazione trasversale a tutti.
Quindi è possibile implementare successivamente le classi di decorazione che avvolgono altre istanze e implementano la preoccupazione trasversale desiderata.
Questo approccio può essere implementato interamente con oggetti Plain Old C# (POCO) e non richiede alcun framework aggiuntivo.
Tuttavia, se ti stanchi di scrivere tutti i decoratori in più, potresti voler utilizzare un quadro. Non ho esperienza con i framework AOP espliciti, ma la maggior parte dei DI contenitori come Castle Windsor offrono funzionalità simili a AOP.
Ecco un esempio di utilizzo di Decoratori. Diciamo che si ha la seguente interfaccia:
public interface IMyInterface
{
void DoStuff(string s);
}
L'implementazione concreta può fare qualcosa di molto interessante, come la scrittura della stringa alla console:
public class ConsoleThing : IMyInterface
{
public void DoStuff(string s)
{
Console.WriteLine(s);
}
}
Se si desidera registrare l'operazione DoStuff, ora è possibile implementare un decoratore di registrazione:
public class LoggingThing : IMyInterface
{
private readonly IMyInterface innerThing;
public LoggingThing(IMyInterface innerThing)
{
this.innerThing = innerThing;
}
public void DoStuff(string s)
{
this.innerThing.DoStuff(s);
Log.Write("DoStuff", s);
}
}
È possibile continuare a scrivere nuovi decoratori, come un decoratore di caching o uno che implementa la sicurezza e così via, e solo wr li apri a vicenda.
Nota: raramente raccomando le interfacce statiche, quindi l'interfaccia Log.Write non è una raccomandazione, ma indica semplicemente un segnaposto. In una vera implementazione, inserivo una sorta di interfaccia di ILogger in LoggingThing.
Ho considerato anche il decoratore.Suppongo che se mantengo i miei metodi abbastanza concisi, non sacrificherò la granularità del controllo che potrei aspettarmi dalle soluzioni esemplificative che ho proposto. C'è qualche motivo per cui preferiresti Decorator? Perché la classe decorata non ha bisogno di conoscenza delle preoccupazioni trasversali? –
Questa è la soluzione che preferisci per i problemi trasversali quando li gestisci? –
Preferisco Decorator rispetto all'iniezione di strategie perché mantiene la vera implementazione squeky clean. Spesso lo preferisco, ma a volte può anche usare l'intercettazione come previsto ad es. Castello Windsor. –