Resumo : neste tutorial, você aprenderá sobre o padrão C# Mediator para encapsular a interação de objetos com acoplamento fraco.
Introdução ao padrão C# Mediator
O padrão Mediator define um objeto (mediador) que encapsula as interações de outros objetos. O padrão Mediator promove acoplamento fraco, evitando que os objetos se refiram explicitamente e permite que você gerencie sua interação de forma independente.
No padrão Mediador, um objeto mediador serve como intermediário entre objetos que precisam interagir entre si.
Portanto, em vez de permitir que os objetos interajam diretamente entre si, eles se comunicam por meio do objeto mediador. O objeto Mediador também pode fornecer um ponto de controle centralizado para coordenar as interações entre os objetos:
O padrão Mediador promove acoplamento fraco entre objetos porque eles não precisam saber os detalhes um do outro e possuem apenas as informações sobre o objeto mediador. Isso permite que o sistema seja mais fácil de manter e modificar porque as alterações em um objeto não afetarão os outros.
O diagrama UML a seguir ilustra o padrão Mediador:
Neste diagrama:
Mediator
define uma interface para comunicação comColleague
objetos.ConcreteMediator
implementa comportamento cooperativo coordenandoColleague
objetos. OConcreteMeditor
mantém uma lista de colegas.Colleague
é uma interface ou classe abstrata que define objetos que precisam interagir entre si.ConcreteColleague
é uma classe concreta daColleague
classe.
O seguinte mostra uma implementação do padrão Mediator em C#:
namespace MediatorPattern;
public abstract class Mediator
{
public abstract void Send(string message, Colleague colleague);
}
public abstract class Colleague
{
private Mediator _mediator;
public Colleague(Mediator mediator)
{
_mediator = mediator;
}
public virtual void Send(string message)
{
_mediator.Send(message, this);
}
public abstract void Receive(string message);
}
public class Colleague1 : Colleague
{
public Colleague1(Mediator mediator) : base(mediator)
{
}
public override void Receive(string message) => Console.WriteLine($"Colleague1 received {message}");
}
public class Colleague2 : Colleague
{
public Colleague2(Mediator mediator) : base(mediator)
{
}
public override void Receive(string message) => Console.WriteLine($"Colleague2 received {message}");
}
public class ConcreteMediator : Mediator
{
public Colleague1 Colleague1;
public Colleague2 Colleague2;
public override void Send(string message, Colleague colleague)
{
if (colleague == Colleague1)
{
Colleague2.Receive($"{message} from {nameof(Colleague1)}");
}
else if (colleague == Colleague2)
{
Colleague1.Receive($"{message} from {nameof(Colleague2)}");
}
}
}
public class Program
{
public static void Main(string[] args)
{
var mediator = new ConcreteMediator();
var c1 = new Colleague1(mediator);
var c2 = new Colleague2(mediator);
mediator.Colleague1 = c1;
mediator.Colleague2 = c2;
c1.Send("Hello");
c2.Send("Hi");
c1.Send("Bye");
c2.Send("Bye bye");
}
}
Linguagem de código: C# ( cs )
Como funciona.
Primeiro, defina uma Mediator
classe abstrata que possua o Send()
método para enviar uma mensagem a um Colega:
public abstract class Mediator
{
public abstract void Send(string message, Colleague colleague);
}
Linguagem de código: C# ( cs )
A seguir, defina a Colleague
classe abstrata que serve como classe base para outros objetos colegas:
public abstract class Colleague
{
private Mediator _mediator;
public Colleague(Mediator mediator)
{
_mediator = mediator;
}
public virtual void Send(string message)
{
_mediator.Send(message, this);
}
public abstract void Receive(string message);
}
Linguagem de código: C# ( cs )
O Colleague
objeto conhece o Mediator
objeto. O Send()
método usa o objeto mediador para enviar uma mensagem.
Em seguida, defina duas classes concretas Colleague que herdam da Colleague
classe:
public class Colleague1 : Colleague
{
public Colleague1(Mediator mediator) : base(mediator)
{
}
public override void Receive(string message) => Console.WriteLine($"Colleague1 received {message}");
}
public class Colleague2 : Colleague
{
public Colleague2(Mediator mediator) : base(mediator)
{
}
public override void Receive(string message) => Console.WriteLine($"Colleague2 received {message}");
}
Linguagem de código: C# ( cs )
As classes Colleague1
e Colleague2
implementam o Receive()
método que mostra a mensagem que recebem no console.
Depois disso, defina a
classe que estende a classe Mediator. O ConcreteMediator
conhece ConcreteMediator
Colleague1
e Colleague2
objeta. Seu Send()
método coordena a comunicação entre estes objetos:
public class ConcreteMediator : Mediator
{
public Colleague1 Colleague1;
public Colleague2 Colleague2;
public override void Send(string message, Colleague colleague)
{
if (colleague == Colleague1)
{
Colleague2.Receive($"{message} from {nameof(Colleague1)}");
}
else if (colleague == Colleague2)
{
Colleague1.Receive($"{message} from {nameof(Colleague2)}");
}
}
}
Linguagem de código: C# ( cs )
Por fim, crie os objetos ConcreteMediator
, Colleague1
e Colleague2
e envie mensagens de Colleague1
e Colleague2
:
public class Program
{
public static void Main(string[] args)
{
var mediator = new ConcreteMediator();
var c1 = new Colleague1(mediator);
var c2 = new Colleague2(mediator);
mediator.Colleague1 = c1;
mediator.Colleague2 = c2;
c1.Send("Hello");
c2.Send("Hi");
c1.Send("Bye");
c2.Send("Bye bye");
}
}
Linguagem de código: C# ( cs )
Variante do padrão Mediador C#
O seguinte fornece uma variante do padrão Mediator, mas de uma forma mais elegante:
namespace MediatorPattern;
public abstract class Mediator
{
public abstract void Send(string message, Colleague colleague);
}
public abstract class Colleague
{
public Mediator? Mediator { set; get;}
public virtual void Send(string message) => Mediator?.Send(message, this);
public abstract void Receive(string message);
}
public class Colleague1 : Colleague
{
public override void Receive(string message) => Console.WriteLine($"Colleague1 received {message}");
}
public class Colleague2 : Colleague
{
public override void Receive(string message) => Console.WriteLine($"Colleague2 received {message}");
}
public class ConcreteMediator : Mediator
{
private readonly List<Colleague> _colleagues = new();
public void Register(Colleague colleague)
{
colleague.Mediator = this;
_colleagues.Add(colleague);
}
public override void Send(string message, Colleague receiver)
{
// Send a message from the list of colleagues,
// which are not receiver, to the receiver
_colleagues
.Where(c => c != receiver)
.ToList()
.ForEach(c => c.Receive(message));
}
}
public class Program
{
public static void Run(string[] args)
{
var mediator = new ConcreteMediator();
var c1 = new Colleague1();
var c2 = new Colleague2();
mediator.Register(c1);
mediator.Register(c2);
c1.Send("Hello");
c2.Send("Hi");
c1.Send("Bye");
c2.Send("Bye bye");
}
}
Linguagem de código: C# ( cs )
Nesta implementação:
- A
Colleague
classe possui umaMediator
propriedade para que você possa definir o objeto mediador. - A
ConcreteMediator
classe mantém uma lista deColleague
objetos em vez de fazer referênciaColleague1
diretaColleague2
. - O
Register()
método daConcreteMediator
classe adiciona aColleague
a umaColleague
lista. - O
Send()
método envia uma mensagem de uma lista de colegas exceto o destinatário (colega) para o destinatário (colega)
Padrão de mediador em .NET
O MediatR é um pacote que é uma implementação simples de mediador em . LÍQUIDO.
Resumo
- Use o padrão C# Mediator para encapsular a interação de objetos com acoplamento fraco.