Menu
Coddy logo textTech

Patrón Adapter

Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy. Lección 57 de 70.

El patrón Adapter es un patrón estructural que permite que interfaces incompatibles trabajen juntas. Actúa como un puente entre dos clases, convirtiendo la interfaz de una clase en una interfaz que los clientes esperan. Piensa en él como un adaptador de corriente que te permite conectar un dispositivo europeo a un enchufe estadounidense.

Este patrón es particularmente útil cuando quieres usar una clase existente pero su interfaz no coincide con lo que tu código necesita. En lugar de modificar la clase original (la cual podrías no controlar), creas un adaptador que la envuelve:

// Clase existente con interfaz incompatible
public class OldPrinter
{
    public void PrintMessage(string msg) => Console.WriteLine($"Old: {msg}");
}

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

// El adaptador cierra la brecha
public class PrinterAdapter : IPrinter
{
    private OldPrinter _oldPrinter;
    
    public PrinterAdapter(OldPrinter oldPrinter)
    {
        _oldPrinter = oldPrinter;
    }
    
    public void Print(string text)
    {
        _oldPrinter.PrintMessage(text);  // Delega a la interfaz antigua
    }
}

Ahora su código puede funcionar con la impresora antigua a través de la interfaz esperada:

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

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

El patrón Adapter es invaluable al integrar bibliotecas de terceros o código heredado en tu aplicación. El código del cliente funciona con la interfaz IPrinter, completamente ajeno a que una clase antigua e incompatible realiza el trabajo real entre bastidores.

challenge icon

Desafío

Fácil

Construyamos un sistema de reproducción multimedia usando el patrón Adapter. Tienes una biblioteca de audio existente que reproduce archivos MP3, pero tu aplicación necesita una interfaz unificada que pueda gestionar distintos tipos de medios. Crearás un adaptador para conectar esta brecha, permitiendo que tu reproductor multimedia moderno funcione sin problemas con la biblioteca de audio heredada.

Organizarás tu código en tres archivos:

  • LegacyAudio.cs: Representa una biblioteca existente que no puedes modificar. Crea una clase LegacyAudioPlayer en el espacio de nombres MediaSystem con un método PlayMp3(string filename) que devuelva la cadena "Playing MP3: {filename}". Este es tu "adaptee": la clase con la interfaz incompatible.
  • MediaAdapter.cs: Crea la interfaz y el adaptador en el mismo espacio de nombres. Define una interfaz IMediaPlayer con un método Play(string filename) que devuelva una cadena. Después, crea una clase MediaPlayerAdapter que implemente IMediaPlayer. Tu adaptador debe envolver una instancia de LegacyAudioPlayer (pasada mediante el constructor) y traducir la llamada a Play en una llamada al método PlayMp3 del reproductor heredado.
  • Program.cs: Reúne todo creando el reproductor heredado, envolviéndolo en tu adaptador y usando el adaptador mediante la interfaz IMediaPlayer. Esto demuestra cómo el código cliente puede trabajar con la interfaz moderna mientras el adaptador gestiona la comunicación con el sistema heredado entre bastidores.

Recibirás una entrada:

  • El nombre del archivo que se reproducirá (por ejemplo, song.mp3)

Crea un LegacyAudioPlayer, envuélvelo en un MediaPlayerAdapter, después llama a Play en el adaptador usando la interfaz IMediaPlayer e imprime el resultado.

Por ejemplo, si la entrada es favorite_track.mp3, la salida debería ser:

Playing MP3: favorite_track.mp3

La ventaja de este patrón es que tu código principal solo interactúa con IMediaPlayer: no sabe que una biblioteca de audio heredada está realizando el trabajo real. Si más adelante necesitas admitir una biblioteca heredada diferente, simplemente crearías un adaptador nuevo sin cambiar ningún código cliente.

Pruébalo tú mismo

using System;
using MediaSystem;

class Program
{
    public static void Main(string[] args)
    {
        // Lee la entrada del nombre de archivo
        string filename = Console.ReadLine();
        
        // TODO: Crea una instancia de LegacyAudioPlayer
        
        // TODO: Envuélvelo en un MediaPlayerAdapter
        
        // TODO: Usa el adaptador a través de la interfaz IMediaPlayer
        // e imprime el resultado de llamar a Play con el nombre de archivo
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de C# online