Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

RSS iMasters

[Resolvido] O padrão de projeto Mediator na prática

Recommended Posts

Os padrões de projeto são soluções prontas e testadas que podem ser aplicadas a situações específicas em um projeto de software.

Por acaso você tem um problema relacionado aos padrões? Parabéns, seu problema já foi resolvido! Basta encontrar o padrão que se encaixa ao seu problema. Simples assim.

Por que perder tempo tentando escrever código para um problema que você pensa que seja somente seu, quando na verdade ele é um problema genérico que outros programadores já enfrentaram e JÁ resolveram?

Neste artigo, eu vou tratar do padrão Mediator. Imagine a seguinte situação:

  • Você desenvolveu um website para e-commerce bem simples com 4 páginas em que os usuários podem consultar um catálogo de produtos e realizar compras
  • Nesse cenário, um usuário pode navegar entre as páginas e aí começam os problemas
  • O código em cada página precisa saber quando ir para uma nova página bem como ativar essa nova página39310.gif
  • Dessa forma, e mesmo com apenas 4 páginas, existem muitas possibilidades de conexões e de navegação entre as páginas
  • Esse cenário costuma gerar uma grande quantidade de código duplicado em cada página
  • Para resolver o problema, o padrão Mediator pode ser usado para encapsular todo o código da navegação em um objeto separado de forma
  • Dessa forma, cada página deverá apenas reportar qualquer alteração de estado para o objeto mediator - que saberá qual página deve enviar39311.gif

Definição formal

Define um objeto que encapsula como um conjunto de objetos interage. O padrão Mediator promove um baixo acoplamento evitando que os objetos façam referência uns aos outros de forma explícita, permitindo a você variar o uso da interação de forma independente. [GoF]

Problema

  1. Como permitir que um grupo de objetos se comunique entre si sem que haja acoplamento entre eles?
  2. Como remover o forte acoplamento presente em relacionamentos muitos para muitos?

Solução

Introduzir um mediator: objetos podem se comunicar sem se conhecer.

  • Um objeto Mediador deve encapsular toda a comunicação entre um grupo de objetos
  1. Cada objeto participante conhece o mediador, mas ignora a existência dos outros objetos;
  2. O mediador conhece cada um dos objetos participantes;
  • A interface do Mediador é usada para iniciar a comunicação e receber notificações
  1. O mediador recebe requisições dos remetentes;
  2. O mediador repassa as requisições aos destinatários.

CheckList

  • Identificar uma coleção de objetos que interagem e que se beneficiariam com o desacoplamento mútuo;
  • Encapsular essas interações na abstração de uma nova classe;
  • Criar uma instância dessa nova classe e refazer todos os 'colegas' de objetos para interagir com um único Mediador;
  • Equilibrar o princípio do desacoplamento com o princípio da distribuição de responsabilidade de maneira uniforme;
  • Tomar cuidado para criar um 'Controlador' ou um objeto 'deus'.

Diagrama de Classes UML

39314.gif

(Fonte: Mediator Pattern - Object Oriented Design)

Participantes (Classes)

  1. Mediator: define uma interface para comunicação com os objetos Colleague;
  2. ConcreteMediator: conhece as classes Colleague e mantém uma referência aos objetos Colleague. Ele implementa a comunicação e a transferência de mensagens entre as classes Colleague;
  3. Classes Colleague: mantêm uma referência ao seu objeto Mediator - se comunicam com o Mediator sempre que necessário. De outra forma, se comunicam com um Colleague.

Vantagens

  • Desacoplamento entre os diversos participantes da rede de comunicação (participantes não se conhecem);
  • Eliminação de relacionamentos muitos para muitos (são todos substituídos por relacionamentos um para muitos);
  • A política de comunicações está centralizada no mediador e pode ser alterada sem mexer nos colaboradores.

Desvantagens

  • A centralização pode ser uma fonte de gargalos de desempenho e de risco para o sistema em caso de falha;
  • Na prática, os mediadores tendem a se tornar mais complexos.

(Fonte: 2003, Helder L. S da Rocha)

Padrões Relacionados

  1. Facade: Um mediator simplificado torna-se um padrão Facade se o mediador for a única classe ativa e se as classes Colleagues forem classes passivas;
  2. Adapter: O padrão Mediator apenas media os pedidos entre as classes Colleague;
  3. Observer: Os padrões Mediator e Observer são semelhantes, resolvendo o mesmo problema.

Exemplo de Implementação em VB .NET

O exemplo a seguir demonstra a utilização do padrão Mediator para facilitar a comunicação usando o baixo acoplamento entre os diferentes participantes de um Chat. Este exemplo foi adaptado de original encontrado em Mediator Design Pattern in C# and VB.NET.

Abra o Visual Basic 2010 Express Edition e crie um novo projeto do tipo Console Application com o nome PadraoMediator:

39317.gif

Vamos criar 5 classes em nosso projeto da seguinte forma: no menu Project, clique em Add Class e a seguir informe o nome da classe e clique no botão Add. As classes são:

  1. Participante: representa a classe abstrata Colleague. Mantém uma referência ao seu objeto Mediator e se comunica com o Mediator sempre que necessário, de outra forma se comunica com um participante;
  2. Membro: representa a classe ConcreteColleague e herda de Participante;
  3. NaoMembro: representa a classe ConcreteColleague e herda de Participante;
  4. AbstractChatSala: representa a classe Mediator. Define uma interface para comunicação com os objetos Participante;
  5. ChatSala: representa a classe concreta ConcreteMediator. Conhece as classes Participante, mantém uma referência aos objetos Participante e implementa a comunicação e transferência de mensagens entre os objetos da classes Participante.

Vejamos a seguir o código de cada uma dessas classes:

Participante.vb

''' <summary>

''' A classe 'AbstractColleague'

''' </summary>

MustInherit Class Participante

 

Private _chatsala As Chatsala

Private _nome As String

 

' Construtor

Public Sub New(ByVal nome As String)

Me._nome = nome

End Sub

 

' Pega o nome do participante

Public ReadOnly Property Nome() As String

Get

Return _nome

End Get

End Property

 

' Pega a sala de chat

Public Property Chatsala() As Chatsala

Get

Return _chatsala

End Get

Set(ByVal value As Chatsala)

_chatsala = value

End Set

End Property

 

' Envia mensagem para um dado participante

Public Sub Enviar(ByVal [para] As String, ByVal mensagem As String)

_chatsala.Enviar(_nome, [para], mensagem)

End Sub

 

' Recebe mensagem de um participante

Public Overridable Sub Receber(ByVal [de] As String, ByVal mensagem As String)

Console.WriteLine("{0} para {1}: '{2}'", [de], Nome, mensagem)

End Sub

 

End Class

Membro.vb

''' <summary>

''' A classe 'ConcreteColleague'

''' </summary>

Class Membro

Inherits Participante

 

' Construtor

Public Sub New(ByVal nome As String)

MyBase.New(nome)

End Sub

'sobrescreve o método Receber

Public Overrides Sub Receber(ByVal [de] As String, ByVal mensagem As String)

Console.Write("para Membro : ")

MyBase.Receber([de], mensagem)

End Sub

End Class

NaoMembro.vb

''' <summary>

''' A classe 'ConcreteColleague'

''' </summary>

Class NaoMembro

Inherits Participante

 

' Construtor

Public Sub New(ByVal nome As String)

MyBase.New(nome)

End Sub

'sobrescreve o método Receber

Public Overrides Sub Receber(ByVal [de] As String, ByVal mensagem As String)

Console.Write("Para NaoMembro : ")

MyBase.Receber([de], mensagem)

End Sub

End Class

AbstractChatSala

''' <summary>

''' A classe abstrata 'Mediator'

''' </summary>

MustInherit Class AbstractChatSala

Public MustOverride Sub Registro(ByVal participante As Participante)

Public MustOverride Sub Enviar(ByVal [de] As String, ByVal [para] As String, ByVal message As String)

End Class

ChatSala

''' <summary>

''' A classe concreta 'ConcreteMediator'

''' </summary>

Class Chatsala

Inherits AbstractChatSala

 

Private _participantes As New Dictionary(Of String, Participante)()

 

Public Overrides Sub Registro(ByVal _participante As Participante)

If Not _participantes.ContainsValue(_participante) Then

_participantes(_participante.Nome) = _participante

End If

 

_participante.Chatsala = Me

End Sub

 

Public Overrides Sub Enviar(ByVal [de] As String, ByVal [para] As String, ByVal mensagem As String)

Dim _participante As Participante = _participantes([para])

If _participante IsNot Nothing Then

_participante.Receber([de], mensagem)

End If

End Sub

End Class

No módulo do projeto, inclua o código abaixo no método Main() que irá testar a nossa pequena aplicação:

Module Module1

 

Sub Main()

'Cria uma sala de chat (chatsala)

Dim chatsala As New Chatsala()

 

' cria participantes e faz o registro

Dim Macoratti As Participante = New Membro("Macoratti")

Dim Miriam As Participante = New Membro("Miriam")

Dim Jefferson As Participante = New Membro("Jefferson")

Dim Janice As Participante = New Membro("Janice")

Dim Jessica As Participante = New NaoMembro("Jessica")

 

'registra os participantes

chatsala.Registro(Macoratti)

chatsala.Registro(Miriam)

chatsala.Registro(Jefferson)

chatsala.Registro(Janice)

chatsala.Registro(Jessica)

 

' Inicia o chat

Jessica.Enviar("Janice", "Olá, Janice!")

Miriam.Enviar("Jefferson", "Como vai você")

Jefferson.Enviar("Macoratti", "Tudo bem")

Miriam.Enviar("Janice", "Como você esta ?")

Janice.Enviar("Jessica", "Tudo tranquilo...")

 

' aguarda...

Console.ReadKey()

End Sub

 

End Module

39319.gif

O diagrama de classes para o nosso exemplo feito no BlueJ é exibido a seguir:

39320.gif

O padrão Mediator é muito útil para programadores Visual Basic (principalmente das versões 5 e 6), pois ele é um atalho para a falta de herança. Ele é tipicamente usado em formulários em que o mesmo media por seus controle e componentes.

Deixa suas impressões, compartilhe ideias nos comentários abaixo e pegue o projeto completo aqui: PadraoMediator.zip

Até a próxima!

 

http://imasters.com.br/artigo/21642/dotnet/o-padrao-de-projeto-mediator-na-pratica

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.