Design Patterns – Adapter

Esse padrão não requer muitas apresentações, é também é bem simples, vamos pensar o que acontece na vida real... Utilizávamos nas nossas construções civis um padrão de tomadas e plugues, um belo dia saiu o padrão brasileiro de tomadas e plugues, quando você compra um aparelho que atende a essa norma logo pensa, vou ter que comprar um adaptador para adaptar esse plugue a tomada que esta em casa, pois são padrões (modelos) diferentes

Esse padrão não requer muitas apresentações, é também é bem simples, vamos pensar o que acontece na vida real... Utilizávamos nas nossas construções civis um padrão de tomadas e plugues, um belo dia saiu o padrão brasileiro de tomadas e plugues, quando você compra um aparelho que atende a essa norma logo pensa, vou ter que comprar um adaptador para adaptar esse plugue a tomada que esta em casa, pois são padrões (modelos) diferentes.

Bom com essa historia eu resumi a vida de um Adapter, que será uma classe intermediaria entre outras duas classes, Plugue e tomada.

Vamos criar um padrão com uma classe tomada e uma classe plugue para este padrão, vamos analisar essas classes.

Primeiro padrão:

#region [Padrao1]

 

public interface IPadrao1

{

String Nome { get; set; }

void testar();

}

 

public interface IPadraoTomada1 : IPadrao1

{

void Conectar(IPadrao1 _Plugue);

void Desconectar();

}

 

public class TomadaP1 : IPadraoTomada1

{

public String Nome { get; set; }

IPadrao1 Plugue;

 

public TomadaP1()

{

Nome = "TomadaP1";

}

 

public void testar()

{

if (Plugue != null)

{

Console.WriteLine(" está com o conectado!", Nome, Plugue.Nome);

Plugue.testar();

}

else

{

Console.WriteLine(" está desconectado!", Nome);

}

}

 

public void Conectar(IPadrao1 _Plugue)

{

Plugue = _Plugue;

Console.WriteLine(" conectado!", Plugue.Nome);

}

 

public void Desconectar()

{

Plugue = null;

}

}

 

public class PlugueP1 : IPadrao1

{

public String Nome { get; set; }

 

public PlugueP1()

{

Nome = "PlugueP1";

}

 

public void testar()

{

Console.WriteLine(" funcionando.", Nome);

}

}

 

#endregion

Temos duas interfaces (IPadrao1 e IPadraoTomada1), e temos uma classe TomadaP1 que encapsula um Plugue do padrão IPradrao1, e com seus métodos Conectar, Desconectar e Teste. O plugue tem o método Teste.

Agora vamos ver o segundo padrão:

#region [Padrao2]

 

public interface IPadrao2

{

String Descricao { get; set; }

void Run();

}

 

public interface IPadraoTomada2 : IPadrao2

{

void Plugar(IPadrao2 _Plugue);

void Desplugar();

}

 

public class TomadaP2 : IPadraoTomada2

{

public String Descricao { get; set; }

IPadrao2 Plugue;

 

public TomadaP2()

{

Descricao = "TomadaP2";

}

 

public void Run()

{

if (Plugue != null)

{

Console.WriteLine(" está com o conectado!", Descricao, Plugue.Descricao);

Plugue.Run();

}

else

{

Console.WriteLine(" está desconectado!", Descricao);

}

}

 

public void Plugar(IPadrao2 _Plugue)

{

Plugue = _Plugue;

Console.WriteLine(" conectado!", Plugue.Descricao);

}

 

public void Desplugar()

{

Plugue = null;

}

}

 

public class PlugueP2 : IPadrao2

{

public String Descricao { get; set; }

 

public PlugueP2()

{

Descricao = "PlugueP2";

}

 

public void Run()

{

Console.WriteLine(" funcionando.", Descricao);

}

}

 

#endregion

Também temos duas interfaces, e duas classes, o padrão1 e o padrão2 são respectivamente iguais, ambos servem para conectar e desconectar plugues de seu padrão.

Vamos testar os padrões separadamente.

class Program

{

static void Main(string[] args)

{

TomadaP1 Tomada1 = new TomadaP1();

TomadaP2 Tomada2 = new TomadaP2();

 

PlugueP1 PlugueP1 = new PlugueP1();

PlugueP2 PlugueP2 = new PlugueP2();

 

Tomada1.Conectar(PlugueP1);

Tomada1.testar();

Tomada1.Desconectar();

Tomada1.testar();

 

  

Tomada2.Plugar(PlugueP2);

Tomada2.Run();

Tomada2.Desplugar();

Tomada2.Run();

 

Console.ReadKey();

 

}

}

Mas como no mundo nada satisfaz a todos 100%, vamos imaginar temos que plugar um PlugueP1 em uma TomadaP2 ou vice e versa.

Bom, vamos recorrer ao Design Patterns Adapter, vamos criar um adaptador para ambos os casos.

Vamos criar as classes que serão os adaptadores dos plugues.

#region [Adapters]

 

public class PlugueP1Adapter : IPadrao1

{

IPadrao2 plugueP2;

 

public PlugueP1Adapter(IPadrao2 _PlugueP2)

{

plugueP2 = _PlugueP2;

}

 

public string Nome

{

get

{

return plugueP2.Descricao;

}

set

{

plugueP2.Descricao = value;

}

}

 

public void testar()

{

plugueP2.Run();

}

 

}

 

public class PlugueP2Adapter : IPadrao2

{

IPadrao1 plugueP1;

 

public PlugueP2Adapter(IPadrao1 _PlugueP1)

{

plugueP1 = _PlugueP1;

}

 

public string Descricao

{

get

{

return plugueP1.Nome;

}

set

{

plugueP1.Nome = value;

}

}

 

public void Run()

{

plugueP1.testar();

}

 

}

 

#endregion

As classes implementam a interface para qual classe será adaptada e encapsula um objeto da outra interface que será adaptado.

Desta forma, com o padrão Adapter conseguimos que uma classe X seja manipulada por um objeto que conhece somente a Y, pois passamos para a nossa tomada uma forma de controlar um objeto que ele não conhece e que não serve para ele, e o mais importante, não tivemos que alterar nada as classes alvos.

Chegamos ao fim deste artigo, espero novamente ter conseguido passar a idéia desse conceito. Até a próxima, ahh não se esqueçam de fazer o download do exemplo.

 

Fontes:

FREEMAN, ERIC & FREEMAN, ELISABETH – Use a Cabeça! Padrões de Projetos (Design Patterns), 2ª Edição [http://www.livrariasaraiva.com.br/produto/1995765/]

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados