Menu
Coddy logo textTech

Padrão Adapter

Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy. Lição 57 de 70.

O padrão Adapter é um padrão 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 os clientes esperam. Pense nele como um adaptador de energia que permite conectar um dispositivo europeu a uma tomada americana.

Esse padrão é particularmente útil quando você quer usar uma classe existente, mas a interface dela não corresponde ao que seu código precisa. Em vez de modificar a classe original (que talvez você não controle), você cria um adaptador que a encapsula:

// Classe existente com interface incompatível
public class OldPrinter
{
    public void PrintMessage(string msg) => Console.WriteLine($"Old: {msg}");
}

// Interface que seu código espera
public interface IPrinter
{
    void Print(string text);
}

// O Adapter preenche a lacuna
public class PrinterAdapter : IPrinter
{
    private OldPrinter _oldPrinter;
    
    public PrinterAdapter(OldPrinter oldPrinter)
    {
        _oldPrinter = oldPrinter;
    }
    
    public void Print(string text)
    {
        _oldPrinter.PrintMessage(text);  // Delega para a interface antiga
    }
}

Agora seu código pode funcionar com a impressora antiga por meio da interface esperada:

OldPrinter legacy = new OldPrinter();
IPrinter printer = new PrinterAdapter(legacy);

printer.Print("Hello");  // Antigo: Hello

O padrão Adapter é inestimável ao integrar bibliotecas de terceiros ou código legado ao seu aplicativo. O código do cliente trabalha com a interface IPrinter, sem saber que uma classe antiga e incompatível está realizando o trabalho de fato nos bastidores.

challenge icon

Desafio

Fácil

Vamos construir um sistema de reprodução de mídia usando o padrão Adapter. Você tem uma biblioteca de áudio existente que reproduz arquivos MP3, mas sua aplicação precisa de uma interface unificada capaz de lidar com diferentes tipos de mídia. Você criará um adaptador para conectar essas partes, permitindo que seu reprodutor de mídia moderno funcione perfeitamente com a biblioteca de áudio legada.

Você organizará seu código em três arquivos:

  • LegacyAudio.cs: Isso representa uma biblioteca existente que você não pode modificar. Crie uma classe LegacyAudioPlayer no namespace MediaSystem com um método PlayMp3(string filename) que retorna a string "Playing MP3: {filename}". Esse é o seu "adaptee" — a classe com a interface incompatível.
  • MediaAdapter.cs: Crie a interface e o adaptador no mesmo namespace. Defina uma interface IMediaPlayer com um método Play(string filename) que retorna uma string. Em seguida, crie uma classe MediaPlayerAdapter que implemente IMediaPlayer. Seu adaptador deve encapsular uma instância de LegacyAudioPlayer (passada por meio do construtor) e traduzir a chamada de Play para o método PlayMp3 do reprodutor legado.
  • Program.cs: Reúna tudo criando o reprodutor legado, encapsulando-o no adaptador e usando o adaptador por meio da interface IMediaPlayer. Isso demonstra como o código cliente pode trabalhar com a interface moderna enquanto o adaptador gerencia a comunicação com o sistema legado nos bastidores.

Você receberá uma entrada:

  • O nome do arquivo a ser reproduzido (por exemplo, song.mp3)

Crie um LegacyAudioPlayer, encapsule-o em um MediaPlayerAdapter, depois chame Play no adaptador usando a interface IMediaPlayer e imprima o resultado.

Por exemplo, se a entrada for favorite_track.mp3, a saída deverá ser:

Playing MP3: favorite_track.mp3

A beleza desse padrão é que seu código principal interage apenas com IMediaPlayer — ele não faz ideia de que uma biblioteca de áudio legada está realizando o trabalho de fato. Se mais tarde você precisar oferecer suporte a uma biblioteca legada diferente, bastará criar um novo adaptador sem alterar nenhum código cliente!

Experimente você mesmo

using System;
using MediaSystem;

class Program
{
    public static void Main(string[] args)
    {
        // Leia a entrada do nome do arquivo
        string filename = Console.ReadLine();
        
        // TODO: Crie uma instância de LegacyAudioPlayer
        
        // TODO: Envolva-a em um MediaPlayerAdapter
        
        // TODO: Use o adaptador por meio da interface IMediaPlayer
        // e imprima o resultado da chamada de Play com o nome do arquivo
    }
}
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

Pratique por conta própria: Compilador de C# online