O Padrão Adapter visa facilitar a conversão da interface de uma classe para outra interface que seja mais importante para o cliente, fazendo com que várias classes possam trabalham em conjunto independente das interfaces originais. 

 

Desenho e Reuso

 

Desenhar software Orientado a Objeto não é uma tarefa fácil, desenhar um software Orientado a Objeto que seja reusável é uma tarefa muito mais difícil.

 

Algumas das tarefas são:

 

- Identificar as abstrações corretas.

- Definir classes na granularidade apropriada.

- Estabelecer interfaces, hierarquias e relacionamento.

 

Ou seja, deve-se pensar em tudo isso de forma a evitar o re-desenho, pois precisamos que o software seja flexível, desenhistas experiêntes conseguem criar bons desenhos OO, os que não tem experiência quase sempre entram numa modelagem estruturada.

 

Quais são as diferenças?

 

- Desenhistas experiêntes não tentam resolver todos os problemas usando "receita de bolo" eles procuram reusar soluções que funcionaram bem no passado, são capazes de identificar "padrões" recorrentes nos problemas enfrentados e nas soluções encontradas.

 

Definição de Padrão:

 

" Um padrao é uma solução recorrente para um problema em um determinado contexto " Erich Gamma

" Cada padrão descreve um problema que acontece repetidas vezes no nossos ambiente e então descreve a essência da solução para aquele problema, de forma que você possa usar essa solução um milhão de vezes, mas nunca fazendo duas vezes a mesma coisa " Chistofher Alexander

 

Padrão Adapter  

 

Ser adaptável é ser capaz de mudar para se enquadrar em outro contexto, como o camaleão que muda de cor se camuflando no ambiente para confundir seu predador, no entanto, em OO a palavra mudança não é verdadeira porque esse padrão respeita um dos príncípios gerais de OO "o código deve estar fechado para modificação e aberto para extensão".

 

Dessa forma quero dizer que o padrão adapter só deve ser usado se você não poder modificar sua(s) classe(s).


As vezes, precisamos utilizar métodos de uma classe existente para trabalhar com uma biblioteca também já existente, o desenho ideal para trabalhar dentro desse cenário é criar uma outra classe chamada Adapter que herdará de uma classe existente enquanto ao mesmo tempo implementará uma interface de uma biblioteca existente. O resultado final é que o Adapter pode chamar o método de uma classe existente através da herança, bem como, pode trabalhar com a existente biblioteca, desde que implemente a interface dessa biblioteca.


Segue UML do Padrão Adapter

 

 













- O Adaptee é uma classe existente

- A IInterface é um interface definida numa existente biblioteca

- O Adapter é a classe que você cria, é herdade da classe Adaptee e implementa a interface IInterface.

  Importante notar que você pode invocar o método OperationA da classe Adaptee utilizando o método OperationB da classe Adapter, por isso é muito comum pessoas dizerem que a classe Adapter tem o objetivo de converte uma interface.


Utilizaremos agora um exemplo no mundo real.

Vamos imaginar que temos uma classe chamada Aluno e toda classe Aluno acessa o método de um Adapter que implementa a interface IEstudante de uma biblioteca já existente.


Aluno precisa estar plugado dentro de um Adapter. O Aluno class é o Adaptee.


A forma de fazer isso é criar um Adapter class chamada AlunoAdapter, que herdada classe Alunoenquanto que ao mesmo tempo implementa a interface IEstudante.














 

No adapter nos podemos chamar um método, o método Estudar da classe parente Aluno, então na classe AlunoAdapter nós podemos chamar o método Estudar através da implementação da interface IEstudante que a classe AlunoAdapter faz por meio do método Ler.


Agora vamos ver como isso funciona programaticamente, para isso teremos que pegar um avião e fazer uma breve viagem a objetolandia ;)

 

Importante notar que não precisamos mudar nenhum código da classe Aluno.

 

using System;
using System.Collections.Generic;

namespace DevBrasil
{
     class Program
     {
         static void Main(string[] args)
         {

            List <IEstudante>  listaEstudante = new List <IEstudante>();
            listaEstudante.Add(new Estudante("Pedro José"));
            listaEstudante.Add(new Estudante("Juca Cipó"));
            listaEstudante.Add(new AlunoAdapter("Ana Maria")); //Aluno de classe já existente
            Ler(listaEstudante);
            Console.Read();
         }

         // O código abaixo é de uma biblioteca existente e não precisa ser mudado
         static void Ler(List <IEstudante> listaEstudante)
         {
             foreach (IEstudante estudante in listaEstudante)
             {
                estudante.Ler();
             }
         }
     }

 

     // O código abaixo é de uma biblioteca existente e não precisa ser mudado
     public interface IEstudante
     {
        void Ler();
     }

     public class Estudante : IEstudante
     {
         private string nome;
         public Estudante(string nome)
         {
            this.nome = nome;
         }

        void IEstudante.Ler()
        {
           Console.WriteLine("Estudante " + this.nome + " precisa ler");
        }
     }

 

     // O código abaixo é de uma biblioteca existente e não precisa ser mudado
     public class Aluno
     {
         private string nome;
         public Aluno(string nome)
         {
             this.nome = nome;
         }

         protected void Estudar()
         {
             Console.WriteLine("Aluno" + this.nome + " precisa estudar.");
         }
     }

     public class AlunoAdapter : Aluno, IEstudante
     {
         public AlunoAdapter(string nome) : base(nome) { }
         void IEstudante.Ler()
         {
             base.Estudar(); // chama o construtor da classe Aluno
         }
     } 

 

Quando aplicar :

 

- Deseja-se usar uma classe existente, mas a sua interface não bate com aquela esperada.

- Quer-se criar uma classe reusável que coopera com classes não-relacionadas e não-previstas, que podem não ser compatíveis.

 

Nesse artigo a gente pode notar a importância do Padrão Adapter dentro de um cenário no qual não podemos mudar nossas classes e sim apenas extendê-las, bem como, avaliamos o quanto é importante uma modelagem coesa, experimentada e aprovada, o que garante a qualidade do código e a facilidade para dar manutenção ao mesmo.  

 

Para saber mais:

Aprofunde seu conhecimento sobre C# 

Forum discussão sobre padrões 

Livro : GAMMA, Erich; HELM, Richard; JHONSON, Ralph; VLISSIDES; Jho...

Livro: FREEMAN, Eric; FREEMAN, Elisabeth. Head First Designer Patte...

Livro: FOWLER, Martin, Patterns of Enterprise Application Architect...

Exibições: 517

Comentar

Você precisa ser um membro de DevBrasil para adicionar comentários!

Entrar em DevBrasil

Comentário de Reginaldo Bras Floriano em 29 fevereiro 2012 às 0:48

Isso é OO na integra...

Comentário de Thiago Diniz em 14 fevereiro 2012 às 8:29

É essa abstração que separa bem os bons profissionais dos que acham que fazem alguma coisa.

© 2017   Criado por Ramon Durães.  

Badges  |  Relatar um incidente  |  Termos de serviço