Chegando aos padrões estruturais, este padrão, também conhecido como Wrapper, tem por objetivo converter a interface de uma classe em outra interface, esperada pelos clientes. O Adapter permite que classes com interfaces incompatíveis trabalhem em conjunto – o que, de outra forma, seria impossível.

Uma das motivações mais evidentes para a utilização deste padrão seja, talvez, o consumo de web services por outras tecnologias que não .NET, como Visual Baisc 6.0, por exemplo.

Considere, por exemplo, um web service que fornece a temperatura atualizada de todos os estados do país. Este web service foi desenvolvido com tecnologia .NET e fornece os resultados à aplicações que suportam a mesma tecnologia via XML. Porém, uma agência de turismo, que possui um sistema legado em Visual Basic 6.0 e está satisfeita com o mesmo, gostaria de utilizar as informações sem que seja necessária uma migração. Neste ponto entra o padrão Adapter.

Com este padrão, é possível criar uma classe que seja compatível com a tecnologia da agência de viagens (Visual Basic 6.0) e permita que a mesma utilize o web service que informa a temperatura atualizada nos estados do país (.NET). Além disso, a empresa responsável pelo web service não precisa abdicar da reutilização, que foi, provavelmente, a principal motivação para a criação do serviço, para fornecer suas informações.

Quando usar Adapter?

Use o padrão Adapter quando:

  • Você quiser usar uma classe existente, mas sua interface não corresponder à interface de que necessita;
  • Você quiser criar uma classe reutilizável que coopere com classes não-relacionadas ou não-previstas, ou seja, classes que não necessariamente tenham interfaces compatíveis;
  • (Somente para adaptadores de objetos) Você precisar usar várias subclasses existentes, porém, for impraticável adaptar essas interfaces criando subclasses para cada uma. Um adaptador de objeto pode adaptar a interface da sua classe-mãe.

Estrutura

Um adaptador de classe usa a herança múltipla para adaptar uma interface à outra:

rnppnetadafig01.jpg

Um adaptador de objeto depende da composição de objetos:

rnppnetadafig02.jpg
  • Alvo: define a interface específica do domínio que Cliente usa.
  • Cliente: colabora com objetos compatíveis com a interface de Alvo.
  • Adaptado: define uma interface existente que necessita ser adaptada.
  • Adaptador: adapta a interface do Adaptado à interface de Alvo.

Consequências

Os adaptadores de classes e de objetos têm diferentes soluções de compromisso. Um adaptador de classe:

  • Adapta o Adaptado ao Alvo através do uso efetivo de uma classe Adaptador concreta. Em conseqüência, um adaptador de classe não funcionará quando quisermos adaptar uma classe e todas as suas subclasses;
  • Permite a Adaptador substituir algum comportamento do Adaptado, uma vez que Adaptador é uma subclasse de Adaptado;
  • Introduz somente um objeto, e não é necessário endereçamento indireto adicional para chegar até o Adaptado.

Um adaptador de objeto:

  • Permite a um único Adaptador trabalhar com muitos Adaptados – isto é, o Adaptado em si e todas as suas subclasses (se existirem). O Adaptador também pode acrescentar funcionalidade a todos os Adaptados de uma só vez;
  • Torna mais difícil redefinir um comportamento de Adaptado. Ele exigirá a criação de subclasses de Adaptado e fará com que Adaptador referencie a subclasse ao invés do Adaptado em si.

Exemplo de código

Para ilustrarmos a utilização do padrão Adapter, vamos analisar o código do web service de temperaturas, mencionado no início do artigo, e do adaptador que será oferecido ao desenvolvedor da aplicação Visual Basic 6.0. Abaixo, o código do web service, que é o Adaptado:


Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols

_
_
_
Public Class Service
    Inherits System.Web.Services.WebService

    _
   Public Function RecuperarTemperaturaRJ() As Integer
       Return 40
   End Function

    _
   Public Function RecuperarTemperaturaSP() As Integer
       Return 26
   End Function

End Class

Este web service, para fins de exemplificação da utilização do padrão que estamos discutindo, contém somente 2 métodos: RecuperarTemperaturaRJ e RecuperarTemperaturaSP. Ambos retornam um número aleatório, para facilitar o entendimento. Abaixo, temos o código de uma classe escrita em VB .NET que servirá como Adaptador do web service citado. Esta classe se transformará, posteriormente, em uma DLL, artefato que é perfeitamente compreendido pelo Visual Basic 6.0.


Public Class Adaptador

   Public Function RecuperarTemperaturaRJAdaptado() As Integer

       Dim Servico As New WSAdapter.Service
       Return Servico.RecuperarTemperaturaRJ

   End Function

   Public Function RecuperarTemperaturaSPAdaptado() As Integer

       Dim Servico As New WSAdapter.Service
       Return Servico.RecuperarTemperaturaSP

   End Function

End Class

A classe Adaptador possui exatamente os mesmos métodos que possui o nosso web service, porém, quem fornece o resultado é o web service. A classe nada mais é do que um entregador da informação criada pelo web service. Para que isso fosse possível, foi criada uma web reference entre o projeto da classe Adaptador e o web service. Com isso, a DLL gerada pelo projeto da classe Adaptador poderá, facilmente, se comunicar com o sistema em Visual Basic 6.0 da agência de turismo e com o web service de temperaturas.