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("{0} está com o {1} conectado!", Nome, Plugue.Nome);

            Plugue.testar();

        }

        else

        {

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

        }

    }

 

    public void Conectar(IPadrao1 _Plugue)

    {

        Plugue = _Plugue;

        Console.WriteLine("{0} 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("{0} 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("{0} está com o {1} conectado!", Descricao, Plugue.Descricao);

            Plugue.Run();

        }

        else

        {

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

        }

    }

 

    public void Plugar(IPadrao2 _Plugue)

    {

        Plugue = _Plugue;

        Console.WriteLine("{0} 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("{0} 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/]