Articoli di programmazione

Design patterns in pillole: Mediator

Il Design Pattern Mediator incapsula la logica con cui più oggetti interagiscono tra loro, evitano che debbano dialogar direttamente

Mediator_design_pattern.png
Il pattern Mediator è tornato alla ribalta da qualche anno, dopo che molti professionisti hanno abbracciato architetture CQRS per cui avevano bisogno di mediare tra i propri Command e CommandHandler. In C# è molto utilizzato il pacchetto Mediatr, che si basa appunto sul design pattern Mediator, che facilita questo compito.


Nel seguente codice, il Mediator è implementato nella classe ChatMediator che si occupa di registrare i vari utenti e metterli in comunicazione chiamando il loro metodo Receive. Da notare che gli User non dialogano mai direttamente ma solo attraverso il Mediator.

class MediatorExample
{
public void Execute()
{
var u = new User();
u.Name = "Giordano";
var u2 = new User();
u2.Name = "Dario";
var m = new ChatMediator();
m.Register(u);
m.Register(u2);
m.Send(u, u2, "Ciao Dario, come stai?");
m.Send(u2, u, "Ciao Giordano, tutto bene grazie!");
}
}

class User
{
public string Name { get; set; }
public void Receive(string from, string message)
{
Console.WriteLine($"Message: {message} (received from {from})");
}
}

class ChatMediator
{
Dictionary d = new Dictionary();
public void Register(User u)
{
if (!d.ContainsKey(u.Name))
d.Add(u.Name, u);
}
public void Send(User from, User to, string message)
{
if (d.ContainsKey(to.Name))
d[to.Name].Receive(from.Name, message);
}
}


Abbiamo parlato di Mediatr all'inizio dell'articolo. Ecco un semplice esempio di come funzioni un binomio Request, RequestHandler con Mediatr. Mediatr espone le interfacce IRequest e IRequestHandler; basta implementarle nei nostri oggetti ed il gioco è fatto:

public class WeatherRequestedEvent : IRequest
{
public WeatherRequestedEvent(string message)
{
Message = message;
}
public string Message { get; }
}

public class WeatherRequestHandler : IRequestHandler
{
public WeatherRequestHandler() {}
public async Task Handle(WeatherRequestedEvent request, CancellationToken cancellationToken)
{
return request.Message + " - Handler ha ricevuto il messaggio alle " + DateTime.Now;
}
}

...
// send the Request to Mediatr
string result = await mediator.Send(new WeatherRequestedEvent("Ecco il mio messaggio"));


#programmazione #designPatterns