Files

title, category, language, tag
title category language tag
Adapter Structural pt
Gang of Four

Também conhecido como

Wrapper

Propósito

Converter a interface de uma classe em outra que o cliente espera. O padrão Adapter permite que uma classe funcione em conjunto com outras classes que não poderiam por problemas de imcompatibilidade de interfaces.

Explicação

Exemplo do mundo real

Considere que você possui algumas imagens no seu cartão de memória e precisa transferí-las para seu computador. Para isso, você irá precisar de algum tipo de adaptador que seja compatível com alguma entrada de seu computador, então você poderá conectar o cartão de memória no seu computador. Nesse caso, o leitor de cartões de memória é um adaptador (Adapter). Outro exemplo poderia ser o famoso adaptador elétrico; um plug de três pinos não pode ser conectado a uma tomada de dois oríficios, é necessário usar um adaptador que fará com que haja compatibilidade entre a tomada e o plugue. Outro exemplo ainda poderia ser um tradutor traduzindo palavras ditas por uma pessoa para outra.

Em outras palavras

O padrão Adapter permite que você envolva um objeto incompatível em um adaptador que o transforma em um objeto compatível com outra classe.

Wikipedia diz

Em engenharia de software, o padrão Adapter é um padrão de projeto de software que permite a interface de uma classe existente ser usada como outra interface. É frequentemente usada para fazer classes já existentes funcionarem com outras, sem modificar seu código fonte.

Exemplo de programação

Considere um capitão que pode apenas usar botes a remo e não pode navegar de outro modo.

Primeiramente, temos as interfaces RowingBoat e FishingBoat

public interface RowingBoat {
  void row();
}

@Slf4j
public class FishingBoat {
  public void sail() {
    LOGGER.info("The fishing boat is sailing");
  }
}

E o capitão espera uma implementação da interface RowingBoat para ser capaz de se mover

public class Captain {

  private final RowingBoat rowingBoat;
  // default constructor and setter for rowingBoat
  public Captain(RowingBoat rowingBoat) {
    this.rowingBoat = rowingBoat;
  }

  public void row() {
    rowingBoat.row();
  }
}

Agora, digamos que os piratas estão chegando e nosso capitão precisa escapar, mas há apenas um bote de pesca disponível. Nós precisamos criar um adaptador que permita o capitão operar o bote de pesca com suas habilidades de condução do bote a remo.

@Slf4j
public class FishingBoatAdapter implements RowingBoat {

  private final FishingBoat boat;

  public FishingBoatAdapter() {
    boat = new FishingBoat();
  }

  @Override
  public void row() {
    boat.sail();
  }
}

E agora o Captain pode usar o FishingBoat para escapar dos piratas.

var captain = new Captain(new FishingBoatAdapter());
captain.row();

Diagrama de classes

alt text

Aplicabilidade

Use o padrão Adapter quando

  • Você quer usar uma classe existente, e sua interface não combina exatamente com o que você precisa
  • Você quer criar uma classe reusável que contribui com classes não relacionadas ou não previstas, isto é, classes que não necessariamente tem interfaces compatíveis
  • Você precisa utilizar várias subclasses existentes, mas é impraticável adaptar suas interfaces criando novas subclasses para cada uma. Um adapter pode adaptar a interface da sua classe pai.
  • A maioria das aplicações que usa bibliotecas de terceiros usa apdaters como uma camada intermediária entre a aplicação e a biblioteca de terceiro para desacoplar a aplicação da biblioteca externa. Se outra biblioteca precisar ser usada, será necessário apenas adequar o adapter para essa nova biblioteca, sem necessidade de alterar muito código.

Tutoriais (em inglês)

Consequências

Classes e objetos adapter tem diferentes prós e contras. Uma classe adapter

  • Converte o objeto adaptado para o alvo por meio de uma classe concreta. Como consequência, uma classe adapter não irá funcionar se desejamos adaptar uma classe e todas as suas subclasses.
  • Deixa o Adapter sobrescrever algum comportamento da classe adaptada já que o Adapter é uma subclasse da classe adaptada.
  • Introduz apenas um objeto, e nenhum ponteiro indireto é necessário para obter a classe adaptada.

Um objeto adapter

  • Permite um único adaptador funcionar com vários objetos adaptados, isto é, o objeto adaptado em si e todas as suas subclasses (se houver). O adapter também pode adicionar funcionalidade a todas os objetos adaptados de uma vez só.
  • Torna mais difícil sobrescrever o comportamento do objeto adaptado. Isso irá requerer geração de subclasses para o objeto adaptado e fazer o adapter se referir a essa subclasse em vez do objeto adaptado em si.

Exemplos do mundo real

Créditos