Menu
Coddy logo textTech

Padrão Adapter

Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 71 de 87.

O Adapter Pattern é um padrão de projeto estrutural que permite que interfaces incompatíveis trabalhem juntas. Ele atua como uma ponte entre duas classes, convertendo a interface de uma classe em uma interface que o cliente espera. Pense nele como um adaptador de tomada que permite conectar um dispositivo europeu em uma tomada americana.

Imagine que você tem uma interface MediaPlayer existente que reproduz arquivos de áudio, mas você precisa integrar uma biblioteca de terceiros que usa uma interface completamente diferente para reproduzir vídeos:

// Interface existente que seu código usa
interface MediaPlayer {
    void play(String filename);
}

// Classe de terceiros com interface incompatível
class AdvancedVideoPlayer {
    public void playVideo(String filename) {
        System.out.println("Playing video: " + filename);
    }
}

O adaptador envolve a classe incompatível e implementa a interface esperada, traduzindo as chamadas entre elas:

class VideoPlayerAdapter implements MediaPlayer {
    private AdvancedVideoPlayer videoPlayer;
    
    public VideoPlayerAdapter() {
        this.videoPlayer = new AdvancedVideoPlayer();
    }
    
    public void play(String filename) {
        videoPlayer.playVideo(filename);
    }
}

Agora o seu código cliente pode usar o reprodutor de vídeo através da familiar interface MediaPlayer:

MediaPlayer player = new VideoPlayerAdapter();
player.play("movie.mp4");  // Saída: Reproduzindo vídeo: movie.mp4

O Padrão Adapter é inestimável ao integrar código legado ou bibliotecas de terceiros sem modificar seu código-fonte. O cliente não percebe que está trabalhando com uma classe adaptada — ele simplesmente usa a interface que conhece.

challenge icon

Desafio

Fácil

Vamos construir um sistema de conversão de temperatura usando o Padrão Adapter! Você tem uma aplicação meteorológica existente que trabalha com temperaturas em Celsius, mas precisa integrar um sensor de temperatura legado que apenas fornece leituras em Fahrenheit. Em vez de modificar qualquer um dos sistemas, você criará um adaptador que preenche essa lacuna.

Você organizará seu código em quatro arquivos:

  • TemperatureProvider.java: Defina a interface que sua aplicação meteorológica espera. Ela deve declarar um método getTemperatureCelsius() que retorna um double representando a temperatura em Celsius.
  • FahrenheitSensor.java: Isso representa o sensor legado com uma interface incompatível. Crie uma classe com um campo double privado para a temperatura em Fahrenheit, definido através do construtor. Ela deve ter um método readFahrenheit() que retorna o valor em Fahrenheit armazenado.
  • SensorAdapter.java: Crie o adaptador que torna o sensor Fahrenheit compatível com sua aplicação meteorológica. Seu adaptador deve implementar TemperatureProvider e envolver um FahrenheitSensor. Quando getTemperatureCelsius() for chamado, ele deve ler do sensor e converter o valor para Celsius usando a fórmula: (fahrenheit - 32) * 5 / 9.
  • Main.java: Reúna tudo! Você receberá uma entrada: uma leitura de temperatura em Fahrenheit (double).

    Crie um FahrenheitSensor com o valor de entrada. Em seguida, crie um SensorAdapter que envolva este sensor. Armazene o adaptador em uma variável do tipo TemperatureProvider para demonstrar que sua aplicação meteorológica pode usá-lo através da interface esperada.

    Imprima o resultado neste formato: "Temperature: " + String.format("%.1f", celsius) + " C" onde celsius é formatado com uma casa decimal.

Você receberá uma entrada: a temperatura em Fahrenheit (double).

Por exemplo, com a entrada 98.6, sua saída seria:

Temperature: 37.0 C

Observe como sua classe Main trabalha inteiramente com a interface TemperatureProvider — ela não tem ideia de que a temperatura real está vindo de um sensor Fahrenheit sendo adaptado nos bastidores. Esta é a elegância do Padrão Adapter!

Folha de consulta

O Adapter Pattern (Padrão Adaptador) é um padrão de design estrutural que permite que interfaces incompatíveis trabalhem juntas, agindo como uma ponte entre duas classes, convertendo uma interface em outra que o cliente espera.

Componentes Chave

  • Target Interface (Interface Alvo): A interface que o cliente espera usar
  • Adaptee (Adaptado): A classe existente com uma interface incompatível
  • Adapter (Adaptador): A classe que implementa a interface alvo e envolve o adaptado, traduzindo as chamadas entre eles

Estrutura Básica

// Target interface
interface MediaPlayer {
    void play(String filename);
}

// Adaptee (incompatible class)
class AdvancedVideoPlayer {
    public void playVideo(String filename) {
        System.out.println("Playing video: " + filename);
    }
}

// Adapter
class VideoPlayerAdapter implements MediaPlayer {
    private AdvancedVideoPlayer videoPlayer;
    
    public VideoPlayerAdapter() {
        this.videoPlayer = new AdvancedVideoPlayer();
    }
    
    public void play(String filename) {
        videoPlayer.playVideo(filename);
    }
}

// Client usage
MediaPlayer player = new VideoPlayerAdapter();
player.play("movie.mp4");  // Output: Playing video: movie.mp4

Quando Usar

O Adapter Pattern é útil quando:

  • Integrar código legado ou bibliotecas de terceiros sem modificar seu código-fonte
  • Fazer com que interfaces incompatíveis trabalhem juntas
  • O cliente precisa permanecer alheio à implementação adaptada

Experimente você mesmo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double fahrenheit = scanner.nextDouble();
        
        // TODO: Crie um FahrenheitSensor com o valor de entrada
        
        // TODO: Crie um SensorAdapter que envolva o sensor
        
        // TODO: Armazene o adaptador em uma variável TemperatureProvider
        
        // TODO: Obtenha a temperatura em Celsius e a imprima
        // Formato: "Temperature: [celsius] C" com uma casa decimal
        // Dica: Use String.format("%.1f", value) para formatação
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos